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; }