标签:搜索
Description
Input
Output
Sample Input
bwwb bbwb bwwb bwww
Sample Output
4
这题看了别人的思路,自己写出来了。首先要想清楚一点,就是如果可以翻成功的话,最多只要16次,即每个点都翻一次,因为对于每一个点,翻动两次和没有翻该点及周围4个点状况是一样的(可以画下图),所以只需考虑16步,依次从1累加到16,看能不能使得图中每个点都为‘b‘或者都为‘w‘,图总共有2^16次不同形态。这道题学到一点,就是二维数组做函数参数的时候,不能写成void f(s[][]),第二维一定要有大小,如void f(s[][10]),或者直接写成void f(s[6][10])。
#include<stdio.h> #include<string.h> char s[6][10]; int flag,step; int tab[10][2]={{0,0},{0,1},{-1,0},{0,-1},{1,0}}; int panduan(char s[6][10]){ int i,j; char c=s[0][0]; for(i=0;i<4;i++){ for(j=0;j<4;j++){ if(s[i][j]!=c) return 0; } } return 1; } void flip(int row,int col) { int i,j,xx,yy; if(s[row][col]==‘w‘) s[row][col]=‘b‘; else s[row][col]=‘w‘; for(i=1;i<=4;i++){ xx=row+tab[i][0]; yy=col+tab[i][1]; if(xx>=0 && xx<=3 && yy>=0 && yy<=3){ if(s[xx][yy]==‘w‘)s[xx][yy]=‘b‘; else s[xx][yy]=‘w‘; } } } void dfs(int row,int col,int dep) { int i,j; if(dep==step){ flag=panduan(s); return; } if(flag || row==4)return; flip(row,col); if(col<3){ dfs(row,col+1,dep+1); //这里翻点是一行一行翻的 } else dfs(row+1,0,dep+1);//如果当前列数已经是最大了,那么就翻下一行,且列数重新变为0 if(flag)return; flip(row,col); //如果翻这一个点不能成功的话就翻回这个点,但注意只是这个点,而不是把翻这个点后面所形成的所有情况都清除,我在这里想了很久。 if(col<3){ dfs(row,col+1,dep);//这里因为这个点(row,col)不翻动,所以还是当前步数还是dep } else dfs(row+1,0,dep); return; } int main() { int n,m,i,j; while(scanf("%s",s[0])!=EOF) { for(i=1;i<4;i++){ scanf("%s",s[i]); } if(panduan(s)){ printf("0\n");continue; } for(step=1;step<=16;step++){ flag=0; dfs(0,0,0); if(flag)break; } if(flag){ printf("%d\n",step); } else printf("Impossible\n"); } return 0; }
标签:搜索
原文地址:http://blog.csdn.net/kirito_acmer/article/details/45397599