【题目链接】click here~~

【题目大意】:

农夫约翰知道聪明的牛产奶多。

于是为了提高牛的智商他准备了例如以下游戏。

有一个M×N 的格子,每一个格子能够翻转正反面,它们一面是黑色,还有一面是白色。黑色的格子翻转后就是白色。白色的格子翻转过来则是黑色。

游戏要做的就是把全部的格子都翻转成白色。

只是由于牛蹄非常大,所以每次翻转一个格子时。与它上下左右相邻接的格子也会被翻转。由于翻格子太麻烦了。所以牛都想通过尽可能少的次数把全部格子都翻成白色。如今给定了每一个格子的颜色。请求出用最小步数完毕时每一个格子翻转的次数。最小步数的解有多个时,输出字典序最小的一组。解不存在的话,则输出IMPOSSIBLE。

【解题思路】:

首先。同一个格子翻转两次的话就会恢复原状,所以多次翻转是多余的。此外。翻转的格子的集合相同的话。其次序是无关紧要的。

因此,总共同拥有2NM种翻转的方法。只是这个解空间太大了,我们须要想出更有效的办法。让我们再回想一下前面的问题。在那道题中,让最左端的牛反转的方法仅仅有1种,于是用直接推断的方法确定就能够了。

相同的方法在这里还行得通吗?最好还是先看看最左上角的格子。

在这里。除了翻转(1,1)之外,翻转(1,2)和(2,1)也能够把这个格子翻转,所以像之前那样直接确定的办法行不通。于是最好还是先指定好最上面一行的翻转方法。此时能够翻转(1,1)的仅仅剩下(2,1)了,所以能够直接推断(2,1)是否须要翻转。类似地(2,1)~(2,N)都能这样推断。如此重复下去就能够确定全部格子的翻转方法。最后(M,1)~(M,N)假设并不是全为白色,就意味着不存在可行的操作方法。像这样。先确定第一行的翻转方式,然后能够非常easy推断这样是否存在解以及解的最小步数是多

少,这样将第一行的全部翻转方式都尝试一次就能求出整个问题的最小步数。

这个算法中最上面一行的翻转方式共同拥有2N种,复杂度为O(MN2N)。

代码:

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif #include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime> #if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif // C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector> #if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif using namespace std; #define rep(i,j,k) for(int i=(int)j;i<(int)k;++i)
#define per(i,j,k) for(int i=(int)j;i>(int)k;--i)
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b? b:a
#define mem(a,b) memset(a,b,sizeof(a)) typedef long long LL;
typedef unsigned long long LLU;
typedef double db;
const int N=16;
const int inf=0x3f3f3f3f;
int n,m,t,ans,res,cnt,tmp; char str[N];
bool vis[N];
int mat[N][N];///状态之前
int flip[N][N];///状态中间
int Res[N][N];///状态之后 int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
int movv[5][2]= {{1,0},{0,1},{0,0},{-1,0},{0,-1}}; using namespace std; inline LL read()
{
int c=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
return c*f;
} bool ok(int dx,int dy)
{
if(dx>=0&&dx<n&&dy>=0&&dy<m) return true;
return false;
}
void getMat()///输入
{
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
scanf("%d",&mat[i][j]);
} int getChange(int x,int y)///推断x,y的颜色
{
int c=mat[x][y];
for(int i=0; i<5; ++i)
{
int dx=x+movv[i][0];
int dy=y+movv[i][1];
if(ok(dx,dy))c+=flip[dx][dy];
}
return c&1;///奇数为1。偶数为0
}
int calc()
{
///求出第二行開始的翻转方法
for(int i=1; i<n; ++i){
for(int j=0; j<m; ++j){
if(getChange(i-1,j)!=0)///是白色翻转
flip[i][j]=1;
}
}
///推断最后一行是否全白
for(int j=0; j<m; ++j){
if(getChange(n-1,j)!=0)
return -1;
}
int sum=0;///统计翻转次数
for(int i=0; i<n; ++i){
for(int j=0; j<m; ++j){
sum+=flip[i][j];
}
}
return sum;
}
void solve()
{
int res=inf;
for(int i=0; i< (1<<m); ++i){///枚举第一行的情况
mem(flip,0);
for(int j=0; j<m; j++){
flip[0][m-j-1] = i >> j & 1;
}
int now=calc();
if(now>=0&&now<res){
res=now;
memcpy(Res,flip,sizeof(flip));
}
}
if(res!=inf){
for(int i=0; i<n; ++i){
for(int j=0; j<m; ++j){
printf("%d%c",Res[i][j],j==m-1? '\n':' ');
}
}
}
else puts("IMPOSSIBLE");
}
int main()
{
while(cin>>n>>m){
getMat();
solve();
}
return 0;
}
</span>

POJ 3279 Fliptile (二进制+搜索)的更多相关文章

  1. poj 3279 Fliptile(二进制搜索)

    Farmer John knows that an intellectually satisfied cow is a happy cow who will give more milk. He ha ...

  2. POJ.3279 Fliptile (搜索+二进制枚举+开关问题)

    POJ.3279 Fliptile (搜索+二进制枚举+开关问题) 题意分析 题意大概就是给出一个map,由01组成,每次可以选取按其中某一个位置,按此位置之后,此位置及其直接相连(上下左右)的位置( ...

  3. poj 3279 Fliptile (简单搜索)

    Fliptile Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16558   Accepted: 6056 Descrip ...

  4. poj 3279 Fliptile(二进制)

    http://poj.org/problem?id=3279 在n*N的矩阵上,0代表白色,1代表黑色,每次选取一个点可以其颜色换过来,即白色变成黑色,黑色变成白色,而且其上下左右的点颜色也要交换,求 ...

  5. POJ 3279 Fliptile[二进制状压DP]

    题目链接[http://poj.org/problem?id=3279] 题意:给出一个大小为M*N(1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的图,图中每个格子代表一个灯泡,mp[i][j] ...

  6. POJ 3279 Fliptile (二进制枚举)

    <题目链接> <转载于 >>> > 题目大意: 给定一个M*N矩阵,有些是黑色(1表示)否则白色(0表示),每翻转一个(i,j),会使得它和它周围4个格变为另 ...

  7. POJ 3279 Fliptile(翻格子)

    POJ 3279 Fliptile(翻格子) Time Limit: 2000MS    Memory Limit: 65536K Description - 题目描述 Farmer John kno ...

  8. 状态压缩+枚举 POJ 3279 Fliptile

    题目传送门 /* 题意:问最少翻转几次使得棋子都变白,输出翻转的位置 状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转 */ #include < ...

  9. POJ 3279(Fliptile)题解

    以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定长宽的黑白棋棋盘摆满棋子,每次操作可以反转一个位置和其上下左右共五个位置的棋子的颜色,求要使用最少翻转次数将所有棋子反转为黑 ...

随机推荐

  1. One switched-capacitor IC simultaneously inverts, doubles, and halves the input voltage.

  2. 重装Windows系统后,Mysql的恢复

    在原地直接恢复MySQL的自动启动的数据库服务,操作如下. (1)环境变量里配置一下Mysql的bin目录 (2)管理员方式启动cmd,运行命令mysqld –install (3)启动Mysql服务 ...

  3. 介紹 IIS 8 全新的 HttpPlatformHandler 模組與 ASP.NET 5 Beta8 重大變更

    HttpPlatformHandler 是一個支援 IIS 8 與 IIS 8.5 的原生模組 (native module),主要使用於 Microsoft Azure Websites 網站服務中 ...

  4. 设计原则:消除Switch...Case的过程,可能有点过度设计了。

    备注 不要重复自己,也不要重复别人,一旦养成了“拷贝和粘贴”的习惯,写程序的时候非常容易导致重复,好在一直暗示自己要稍后进行重构,本文给出一个重构的示例. 需求 需求:按照年.月和日显示销售数据,根据 ...

  5. 第八章openwrt 703N使用HUB(集线器)插U盘等设备

    在这里就要吐槽一下了,在网上一搜索竟然没有一篇详细的关于703N使用hub后挂载u盘的文章,想了很久问了别人还弄了一天晚上终于弄好了.好吧下面开始言归正传: 1.其实一般质量可以的集线器例如SSK这类 ...

  6. POJ 1737 Connected Graph 题解(未完成)

    Connected Graph Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3156   Accepted: 1533 D ...

  7. cocos2d-x v3.0各个环境下创建项目以及编译、执行官方DEMO

    摘自:https://github.com/cocos2d/cocos2d-x/ 怎样创建一个新项目 How to start a new game Download the code from co ...

  8. SpringMVC之HandlerMethodArgumentResolver和<mvc:argument-resolvers>

    SpringMVC提供了一个HandlerMethodArgumentResolver接口可以让我们处理方法的参数,和注解结合提来,能有很强大的功能,例如SpringMVC提供的@ModelAttri ...

  9. 解决引用openssl静态库libcrypto.a和libssl.a出现undefined reference to错误的问题

    最近在做使用openssl链接http和https的项目,编译时出现以下问题. /usr/local/openssl/lib/libcrypto.a(async.o): In function `as ...

  10. Windows MongoDB安装配置

    1.下载 官网:http://www.runoob.com/mongodb/mongodb-window-install.html 由于是在window下,所以我下载的是mongodb-win32-x ...