链接:http://poj.org/problem?id=1753
题意:一个4*4的方格,有白棋或者黑棋,每次操作是一个位置的颜色翻转,即白变黑、黑变白,并且与它相邻的四个位置的颜色也都跟着改变,问最少要变化多少次才能使所有棋子都是白色或者都是黑色。
思路:不难看出一个棋子翻偶数次和不翻的效果是一样的,并且如果选定了一些棋子翻,翻的顺序对最后的结果是没有影响的,所以可以用DFS去枚举每个棋子的状态:翻或不翻,最多2^16的复杂度就能求出,65536次。
不过我WA了一发,因为每次我在dfs最后一个点的时候,翻完牌还没有判断就退出函数了,因为我写的判断条件是在下一次dfs翻牌之前判断,而最后一个点因为边界问题不会进入下一次dfs,所以再加个单独的判断,就过了
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 810 #define eps 1e-7 #define INF 0x7FFFFFFF typedef long long ll; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 char mapp[10][10]; int mp[10][10]; int ans; bool check(){ int i,j; for(i=0;i<4;i++){ for(j=0;j<4;j++){ if(mp[i][j]!=mp[0][0]) return false; } } return true; } void flip(int x,int y){ if(x+1<4) mp[x+1][y] = !mp[x+1][y]; if(x-1>=0) mp[x-1][y] = !mp[x-1][y]; if(y+1<4) mp[x][y+1] = !mp[x][y+1]; if(y-1>=0) mp[x][y-1] = !mp[x][y-1]; mp[x][y] = !mp[x][y]; } void dfs(int x,int y,int step){ if(step>16) return ; int i, j; bool flag = check(); if(flag){ if(step<ans) ans = step; return ; } flip(x,y); if(y+1<4) dfs(x,y+1,step+1); else if(x+1<4) dfs(x+1,0,step+1); else{ if(check()){ if(step+1<ans) ans = step+1; } } flip(x,y); if(y+1<4) dfs(x,y+1,step); else if(x+1<4) dfs(x+1,0,step); else{ if(check()){ if(step<ans) ans = step; return ; } } } int main(){ int i,j; bool flag ; ans = 20; for(i=0;i<4;i++){ scanf("%s",mapp[i]); for(j=0;j<4;j++){ if(mapp[i][j]=='b') mp[i][j] = 1; } } flag = check(); if(flag) puts("0"); else{ dfs(0,0,0); if(ans<20) cout<<ans<<endl; else cout<<"Impossible"<<endl; } return 0; }
POJ--1753--Flip Game【DFS】,布布扣,bubuko.com
原文地址:http://blog.csdn.net/zzzz40/article/details/38112303