1753 Flip Game dfs
阿新 • • 發佈:2018-12-21
題意:一個4*4的棋盤,每個格子上有一個黑白棋(黑色朝上或白色朝上),定義操作翻轉某個位置的棋子,同時也翻轉其上下左右四個棋子,求把整個棋盤翻轉成都是白色朝上或者黑色朝上的最少步數。
思路:對於某個位置的棋子,我們可以看出翻2次和不翻效果是一樣的,翻3次效果和翻1次效果一樣,所以對於每個位置只有兩種情況:翻1次或者不翻,同時翻的順序對結果也並沒有影響,由此,假設我們已經找到一種翻第一行棋子的策略,那麼要滿足最後是同種顏色朝上,那麼第二行的翻轉策略已經固定只有兩種(一種使第一行白色朝上,一種使第一行黑色朝上),以此類推,所以我們只要列舉第一行的翻轉策略就行了。
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<map> #include<vector> #include<queue> #include<deque> #define ll long long #define PI acos(-1) #define INF 0x3f3f3f3f #define NUM 500020 #define debug true #define lowbit(x) ((-x)&x) #define ffor(i,d,u) for(int i=(d);i<=(u);++i) #define _ffor(i,u,d) for(int i=(u);i>=(d);--i) #define mst(array,Num,Kind,Count) memset(array,Num,sizeof(Kind)*(Count)) using std::min; const int P = 1e9+7; bool ch[5][5],ch1[5][5]; int ans; template <typename T> void read(T& x) { x=0; char c;T t=1; while(((c=getchar())<'0'||c>'9')&&c!='-'); if(c=='-'){t=-1;c=getchar();} do(x*=10)+=(c-'0');while((c=getchar())>='0'&&c<='9'); x*=t; } template <typename T> void write(T x) { int len=0;char c[21]; if(x<0)putchar('-'),x*=(-1); do{++len;c[len]=(x%10)+'0';}while(x/=10); _ffor(i,len,1)putchar(c[i]); } inline void turn(bool &x) { x = !x; } inline bool check(bool flag) { ffor(i,1,4)if(ch[4][i] != flag)return false; return true; } int tryy(int line,bool flag,int step) { if(line == 5)return (check(flag)?step:INF); ffor(i,1,4) if(ch[line-1][i] != flag) { ch[line-1][i] = flag; if(i > 1)turn(ch[line][i-1]); turn(ch[line][i]); if(i < 4)turn(ch[line][i+1]); if(line < 4)turn(ch[line+1][i]); ++step; } return tryy(line+1,flag,step); } int solve(bool flag) { int ans = INF,step,x; int a[5]; ffor(i,0,15) { x = i; ffor(j,1,4)ch[1][j] = ch1[1][j],a[j] = x%2,x /= 2; ffor(i,2,4)ffor(j,1,4)ch[i][j] = ch1[i][j]; step = 0; ffor(j,1,4) { if(a[j] == 0)continue; turn(ch[1][j]); if(j > 1)turn(ch[1][j-1]); if(j < 4)turn(ch[1][j+1]); turn(ch[2][j]); ++step; } x = tryy(2,flag,step); ans = min(ans,x); } return ans; } inline void AC() { char x; ffor(i,1,4) { ffor(j,1,4)x = getchar(),ch1[i][j] = (x == 'b'); getchar(); } ans = solve(false); ans = min(ans,solve(true)); if(ans == INF)puts("Impossible"); else write(ans),putchar('\n'); } int main() { AC(); return 0; }