Description

Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its  squares. One side of each piece is white and the other one is black and each piece is lying either it's black or white side up. Each round you flip 3 to 5 pieces, thus changing the color of their upper side from black to white and vice versa. The pieces to be flipped are chosen every round according to the following rules:
Choose any one of the pieces.
Flip the chosen piece and also all adjacent pieces to the left, to the right, to the top, and to the bottom of the chosen piece (if there are any).

Consider the following position as an example: 

bwbw
wwww
bbwb
bwwb
Here "b" denotes pieces lying their black side up and "w" denotes pieces lying their white side up. If we choose to flip the 1st piece from the 3rd row (this choice is shown at the picture), then the field will become: bwbw
bwww
wwwb
wwwb
The goal of the game is to flip either all pieces white side up or all pieces black side up. You are to write a program that will search for the minimum number of rounds needed to achieve this goal.

Input

The input consists of  lines with  characters "w" or "b" each that denote game field position.

Output

Write to the output file a single integer number - the minimum number of rounds needed to achieve the goal of the game from the given position. If the goal is initially achieved, then write . If it's impossible to achieve the goal, then write the word "Impossible" (without quotes).

Sample Input

bwwb
bbwb
bwwb
bwww

Sample Output


Source

 
第一种方法是bfs+状态压缩,将整张图压缩为01状态,算出二进制状态的十进制的值。然后跑bfs,bfs里面是枚举16个位置的变换,( 这里预处理出变换的值,然后进行异或计算),再加个标记vis不就行了。
 #pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
#define ll long long
#define eps 1e-10
#define MOD 1000000007
#define N 1000000
#define inf 1e12 int vis[(<<)];
struct Node{
int val;
int t; }st;
int mp[]={
,,,,,,,,,,,,,,,
};
void bfs(){
queue<Node>q;
q.push(st);
Node t1,t2;
vis[st.val]=;
while(!q.empty()){
t1=q.front();
q.pop();
if(t1.val== || t1.val==((<<)-)){
printf("%d\n",t1.t);
return ;
}
for(int i=;i<;i++){
t2=t1;
t2.val^=mp[i];
if(vis[t2.val]) continue;
vis[t2.val]=;
t2.t++;
q.push(t2);
}
}
printf("Impossible\n");
}
int main()
{
char s[];
int ans=;
int num=;
for(int i=;i<;i++){
scanf("%s",s);
for(int j=;j<;j++){
if(s[j]=='b'){
ans+=(<<num);
}
num--;
}
}
st.val=ans;
st.t=;
memset(vis,,sizeof(vis));
bfs(); return ;
}
 
第二种方法是dfs枚举。

思路:仔细考虑,可以发现,一个位置的棋子,要么保持原状不变,要么改变一次。因为改变偶数次和不改变的效果是一样的,改变奇数次和改变1次的效果是一样的。也就是说,达到最后颜色都一样的状态,某个位置的棋子,要么改变一次,要么一次也不改变。所以求最少经过多少步的改变,可以转化为最少需要改变多少个棋子。因为数据范围小,总共16个棋子,所以我们可以枚举。

我们可以判断改变0个,改变1个,改变2个,,,改变16个。改变x个,就是从16个元素中选x个的过程,可以用dfs实现。如果一直到最后改变16个都不行,则输出“Impossible”即可。

 #pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<queue>
#include<set>
#include<bitset>
#include<map>
#include<vector>
#include<stdlib.h>
using namespace std;
#define max(a,b) (a) > (b) ? (a) : (b)
#define min(a,b) (a) < (b) ? (a) : (b)
#define ll long long
#define eps 1e-10
#define MOD 1000000007
#define N 26
#define inf 1e12
int mp[][];
int newMp[][];
int newRecord[N];
int dirx[]={,,-,};
int diry[]={-,,,};
int flag;
int vis[N];
void judge(int cnt){
for(int i=;i<;i++){
for(int j=;j<;j++){
newMp[i][j]=mp[i][j];
}
}
for(int i=;i<cnt;i++){
int x=newRecord[i]/;
int y=newRecord[i]-x*;
newMp[x][y]=!newMp[x][y];
for(int j=;j<;j++){
int newX=x+dirx[j];
int newY=y+diry[j];
if(newX< || newX>= || newY< || newY>=) continue;
newMp[newX][newY]=!newMp[newX][newY];
}
}
int ans=;
for(int i=;i<;i++){
for(int j=;j<;j++){
if(newMp[i][j]){
ans++;
}
}
}
if(ans== || ans==){
flag=;
}
}
void dfs(int st,int num,int cnt){
if(num==cnt){
judge(cnt);
return;
} for(int i=st;i<;i++){
if(!vis[i]){
vis[i]=;
newRecord[num]=i;
dfs(i,num+,cnt);
if(flag)
return;
vis[i]=;
}
} }
int main()
{
char s[];
for(int i=;i<;i++){
scanf("%s",s);
for(int j=;j<;j++){
if(s[j]=='b'){
mp[i][j]=;
}
else{
mp[i][j]=;
}
}
}
flag=;
for(int i=;i<=;i++){//改变多少个可以达到目的
memset(vis,,sizeof(vis)); dfs(,,i);
if(flag){
printf("%d\n",i);
break;
}
}
if(flag==){
printf("Impossible\n");
} return ;
}

poj 1753 Flip Game(bfs状态压缩 或 dfs枚举)的更多相关文章

  1. POJ 1753 Flip Game (状态压缩 bfs+位运算)

    Flip game is played on a rectangular 4x4 field with two-sided pieces placed on each of its 16 square ...

  2. BFS+状态压缩DP+二分枚举+TSP

    http://acm.hdu.edu.cn/showproblem.php?pid=3681 Prison Break Time Limit: 5000/2000 MS (Java/Others)   ...

  3. ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))

    求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...

  4. 枚举 POJ 1753 Flip Game

    题目地址:http://poj.org/problem?id=1753 /* 这题几乎和POJ 2965一样,DFS函数都不用修改 只要修改一下change规则... 注意:是否初始已经ok了要先判断 ...

  5. HDU1429+bfs+状态压缩

    bfs+状态压缩思路:用2进制表示每个钥匙是否已经被找到.. /* bfs+状态压缩 思路:用2进制表示每个钥匙是否已经被找到. */ #include<algorithm> #inclu ...

  6. BFS+状态压缩 hdu-1885-Key Task

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1885 题目意思: 给一个矩阵,给一个起点多个终点,有些点有墙不能通过,有些点的位置有门,需要拿到相应 ...

  7. BFS+状态压缩 HDU1429

    胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  8. hdoj 5094 Maze 【BFS + 状态压缩】 【好多坑】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  9. poj - 3254 - Corn Fields (状态压缩)

    poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...

随机推荐

  1. PyQt4中无边框窗口的移动(拖动)

    import sys from PyQt4.QtGui import * from PyQt4.Qt import * from PyQt4.QtCore import * class AboutUs ...

  2. Windows下PHP开发环境搭建

    PHP集成开发环境有很多,如XAMPP.AppServ......只要一键安装就把PHP环境给搭建好了.但这种安装方式不够灵活,软件的自由组合不方便,同时也不利于学习.所以我还是喜欢手工搭建PHP开发 ...

  3. [置顶] Java中发邮件的6种方法

    1.官方标准JavaMail Sun(Oracle)官方标准,功能强大,用起来比较繁琐. 官方资料:http://www.oracle.com/technetwork/java/javamail/in ...

  4. 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6621566 上一篇文章Android进程间通信 ...

  5. 关于mybatis插入数据库返回主键id

    关于Sequence主键的数据库来说,如: <insert id="add" parameterType="vo.Category"> <se ...

  6. Linux 编译安装 apache 2.4

    在安装apache之前需要准备一些必要的依赖包 gcc安装: #yum install -y gcc gcc-c++安装: #yum install gcc-c++  apr安装: 下载包:apr-1 ...

  7. JQuery hover(over,out) 使用笔记

    转载自:http://www.douban.com/note/202404884/ JQuery hover(over,out) 使用笔记 JavaScript 下.onmouseover() 和 o ...

  8. doGet和doPost的区别

    1.doGet和doPost的区别,在什么时候调用,为什么有时doPost中套用doGet 2.提交的form     method=Post就执行DOPOST,否则执行GOGET 套用是不管meth ...

  9. 在[self addsubView:xxx]中,self.name 和 _name的区别

    在[self addsubView:xxx]中,self.name 和 _name的区别self.name 会调用重写的getter方法,而_name添加的只是_name 这个成员变量

  10. 被sjy带刷题#1

        笔记[问题描述]给定一个长度为m的序列a,下标编号为1~m.序列的每个元素都是1~n的整数.定义序列的代价为 你现在可以选择两个数x和y,并将序列a中所有的x改成y.x可以与y相等.请求出序列 ...