Description
Consider the following position as an example: 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