題目地址: http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=4304
直接 DFS 枚舉所有可能即可。。
#include<stdio.h>#include<string.h>int s[5][5],res,r[5][5],k[5][5];void output(){ // 這題很早就做出來了。。 查了一小時錯。囧// 錯在最後的輸出 這裡,一直被忽略了,把 r[3][1] 寫成了 r[3][i] 。。。 int i;putchar(' ');for(i=2;i<=3;i++)printf(" %d",r[1][i]);putchar('\n');printf("%d",r[2][1]);for(i=2;i<=4;i++)printf(" %d",r[2][i]);putchar('\n');printf("%d",r[3][1]);for(i=2;i<=4;i++)printf(" %d",r[3][i]);putchar('\n');putchar(' ');for(i=2;i<=3;i++)printf(" %d",r[4][i]);putchar('\n');}int x[12]={1,1,2,2,2,2,3,3,3,3,4,4}; // 記錄所有點的位置 int y[12]={2,3,1,2,3,4,1,2,3,4,2,3};int same(){ // 判斷所有顏色是否一致 int i,sum=0;for(i=0;i<12;i++)if(s[x[i]][y[i]]) sum++;if(sum==0 || sum==12) return 1;else return 0;}void dfs(int num,int i){if(res>2) return;if(num==0){if(same()){res++; // 記錄翻轉成功的次數 if(res==1){ // 記錄第一次 完成任務時的 所改變的位置。 for(int i=0;i<12;i++)r[x[i]][y[i]]=k[x[i]][y[i]];}}return;}for(;i>=num;i--){int t=i-1;for(int j=1;j<=4;j++) // 這裡是翻轉顏色 s[j][y[t]]^=1,s[x[t]][j]^=1;s[x[t]][y[t]]^=1;k[x[t]][y[t]]=1; // 用於記錄每次改變了哪個位置 dfs(num-1,i-1);k[x[t]][y[t]]=0; // dfs 結束之後需要會重新翻轉回來 for(int j=1;j<=4;j++)s[j][y[t]]^=1,s[x[t]][j]^=1;s[x[t]][y[t]]^=1;}}int main(){int t,i,j;scanf("%d",&t);memset(k,0,sizeof(k));while(t--){for(i=0;i<12;i++)scanf("%d",&s[x[i]][y[i]]);// 暴力枚舉每一種情況, 因為最多翻轉12個位置,時間為 2^12 次方 for(i=0;i<=12;i++){ // 從翻轉個數少的開始枚舉,0個、1個、2個、3個 , 等等 res=0;dfs(i,12);if(res>0) break; }printf("%d\n",i);if(res>1) puts("123.cpp");else output();}return 0;}