背景:说实话,看到这道题的时候一点也不会,然后朋友说了用dfs做,虽然曾经学长讲过dfs,但我没有认真听,所以还是一点也没懂,然后百度了dfs,还是晕晕的,最后实在没办法,就看了朋友的代码,这下才弄懂了什么是dfs,我下面的代码就是看了朋友的代码后,凭借记忆,用他的思路写出来的。
思路:对于每个格子,他要么被反转0次,要么1次,由于只有16个格子,所以他的总的情况有
所以采用dfs深度搜索,在时间上是不成问题的。
学习:dfs算法:深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。
#include <stdio.h>
int q[5][5],ok=0;
int iswin(void)
{
int k=q[0][0];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(k!=q[i][j]) return 0;
return 1;
}
void change(int i,int j)
{
q[i][j]=!q[i][j];
if(i-1>=0) q[i-1][j]=!q[i-1][j];
if(j-1>=0) q[i][j-1]=!q[i][j-1];
if(i+1<=3) q[i+1][j]=!q[i+1][j];
if(j+1<=3) q[i][j+1]=!q[i][j+1];
}
void dfs(int m,int sum,int a,int b)
{
if(ok) return;
if(m==sum)
{
if(iswin()) {ok=1;printf("%d\n",sum);}
else return;
}
else
{
for(int i=a;i<4;i++)
{
for(int j=b;j<4;j++)
{
change(i,j);
if(j<3) dfs(m+1,sum,i,j+1);
if(j==3) dfs(m+1,sum,i+1,0);
change(i,j);
}
}
return;
}
}
int main(void)
{
char ch;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
scanf("%c",&ch);
if(j==3) getchar();
q[i][j]=(ch=='b')?1:0;
}
if(iswin()) {printf("%d\n",0);return 0;}
for(int k=1;k<=16;k++)
dfs(0,k,0,0);
if(!ok) printf("Impossible\n");
return 0;
}