【题目链接】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. WICED -- Wireless Internet Connectivity for Embedded Devices

    Broadcom's Wireless Internet Connectivity for Embedded Devices (WICED™) platform (pronounced "w ...

  2. Spring集合 (List,Set,Map,Properties) 实例

    下面例子向您展示Spring如何注入值到集合类型(List, Set, Map, and Properties). 支持4个主要的集合类型: List – <list/> Set – &l ...

  3. 用CSS3来代替JS实现交互

    [CSS3和JS] 对于CSS了解的同学都知道,CSS的实现是最底层的,在实现方式和性能上都不是,JS这种提供接口的脚本可比的:从CSS3的动画和JS动画对比角度来看两者,会更清晰:而且随着前端框架的 ...

  4. react+redux+generation-modation脚手架搭建一个todolist

    TodoList 1. 编写actions.js 2. 分析state 试着拆分成多个reducer 3. 了解store 4. 了解redux数据流生命周期 5. 分析容器组件和展示组件 搞清楚,数 ...

  5. 能使用html/css解决的问题就不要使用JS

    为什么说能使用html/css解决的问题就不要使用JS呢?两个字,因为简单.简单就意味着更快的开发速度,更小的维护成本,同时往往具有更好的体验,下面介绍几个实例. 1. 导航高亮 导航高亮是一种很常见 ...

  6. ClientDataSet的版本兼容性

    ClientDataSet的版本兼容性 在Delphi的早期版本中,Data这个Variant类型的值内部使用的是AnsiString来存贮的字节流,但我并不确定Delphi从什么时候开始,将其改为了 ...

  7. PAT 1033. To Fill or Not to Fill (贪心)

    PAT-A的最后一题,最终做出来了... 是贪心,通过局部最优获得全局最优. 1. 将加油站按距离升序排序 2. 记录当前所在的加油站index,存有的汽油,花费.向后遍历全部 该站可抵达的加油站 3 ...

  8. Python学习(八)异常处理

    Python 异常处理 程序出错时,会抛出异常,这想必在之前学习过程中已经见过不少. 这边具体说明下Python 的标准异常.如何捕捉异常.抛出异常 以及自定义异常. python 标准异常 我们先来 ...

  9. JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别以及接口里default方法

    使用大写字母A,B,C,D......X,Y,Z定义的,就都是泛型,把T换成A也一样,这里T只是名字上的意义而已 ? 表示不确定的java类型 T (type) 表示具体的一个java类型 K V ( ...

  10. Page的ResolveClientUrl与ResolveUrl读取路径

    Page的ResolveClientUrl与ResolveUrl读取路径 . 一.Page对象的ResolveClientUrl与ResolveUrl Page.ResolveClientUrl(): ...