poj 1753 2965
阿新 • • 發佈:2018-12-17
這兩道題類似,前者翻轉上下左右相鄰的棋子,使得棋子同為黑或者同為白。後者翻轉同行同列的所有開關,使得開關全被開啟。
題意:有一4x4棋盤,上面有16枚雙面棋子(一面為黑,一面為白), 當翻動一隻棋子時,該棋子上下左右相鄰的棋子也會同時翻面。以b代表黑麵,w代表白麵,給出一個棋盤狀態, 問從該棋盤狀態開始,使棋盤變成全黑或全白,至少需要翻轉多少步
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int mp[5][5]; int step,flag; int range()//遍歷整個棋盤是否“清一色” { for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(mp[i][j]!=mp[0][0]) return 0; return 1; } void turn(int i,int j)//翻轉(i,j)棋子,以及(i,j)周圍的棋子 { mp[i][j]=!mp[i][j]; if(i>0) mp[i-1][j]=!mp[i-1][j]; if(i<3) mp[i+1][j]=!mp[i+1][j]; if(j>0) mp[i][j-1]=!mp[i][j-1]; if(j<3) mp[i][j+1]=!mp[i][j+1]; } int dfs(int i,int j,int k) { if(k==step){ flag = range(); return 0; } if(flag||i==4){ return 1; } turn(i,j); if(j<3) dfs(i,j+1,k+1);//一行當中的所有列 else dfs(i+1,0,k+1);//下一行 turn(i,j);//回溯,翻回來 if(j<3) dfs(i,j+1,k);//下一個棋子繼續dfs else dfs(i+1,0,k); return 0; } int main() { char str[5][5]; for(int i=0;i<4;i++) cin>>str[i]; for(int i=0;i<4;i++) for(int j=0;j<4;j++) if(str[i][j]=='b') mp[i][j]=1; else mp[i][j]=0; for(step=0;step<=16;step++) { flag = 0; dfs(0,0,0);//(x,y),step if(flag) break; } if(flag) printf("%d\n",step); else printf("Impossible\n"); return 0; }