我再输入的时候将*转为1,#转为-1;这样我就可以通过-来进行翻转操作了
int turn(int x,int y)
{
a[x][y]=-a[x][y];
a[x][y+1]=-a[x][y+1];
a[x][y-1]=-a[x][y-1];
a[x-1][y]=-a[x-1][y];
a[x+1][y]=-a[x+1][y];
}
这里我通过每个位置与首位置比较,如果出现不同的则说明,没有胜利
int judge()
{
int i,j;
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
if(a[i][j]!=a[1][1])
return 0;
return 1;
}
int DFS(int i,int j,int count)
{
if(count==step)
{
flag=judge();
return 0;
}
if(flag||i==5) return 1;
turn(i,j);
if(j<4) DFS(i,j+1,count+1);
else DFS(i+1,1,count+1);
turn(i,j);
if(j<4)DFS(i,j+1,count);
else DFS(i+1,1,count);
return 0;
}
因为一个有4*4=16个坐标位置,假如我们每个位置都操作一边的话,也就是16个位置,所以我们的操作肯定不会超过16次。
所以待会我们用一个for循环来进行1-16次的操作就可以了。
好的现在我们来看看这个DFS函数的意思,
这段的意思是,完成了指定步骤后是否胜利。if(count==step)
{
flag=judge();
return 0;
}
这里是判断是否已经满足胜利条件,或者越界,进行剪枝操作;if(flag||i==5) return 1;
好的,现在到了关键的地方了:
这里我采用的是从左到右然后再跳到下一行从左到右的搜索方式,不断判断有没有符合胜利条件。turn(i,j);
if(j<4) DFS(i,j+1,count+1);
else DFS(i+1,1,count+1);
turn(i,j);
if(j<4)DFS(i,j+1,count);
else DFS(i+1,1,count);
上半部分是直接搜索,下半部分则是进行回溯,大家可以看到下半部分的count是不+1的,这样我就可以实现对整个图形的遍历操作了。
完整代码:
#include<stdio.h>
#include<string.h>
int a[6][6],flag,step;
int turn(int x,int y)
{
a[x][y]=-a[x][y];
a[x][y+1]=-a[x][y+1];
a[x][y-1]=-a[x][y-1];
a[x-1][y]=-a[x-1][y];
a[x+1][y]=-a[x+1][y];
}
int judge()
{
int i,j;
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
if(a[i][j]!=a[1][1])
return 0;
return 1;
}
int DFS(int i,int j,int count)
{
if(count==step)
{
flag=judge();
return 0;
}
if(flag||i==5) return 1;
turn(i,j);
if(j<4) DFS(i,j+1,count+1);
else DFS(i+1,1,count+1);
turn(i,j);
if(j<4)DFS(i,j+1,count);
else DFS(i+1,1,count);
return 0;
}
int main()
{
char A[5][5];
int i,j;
memset(a,0,sizeof(a));
while(~scanf("%s",A[1]))
{
flag=0;
for(i=2;i<=4;i++)
{
scanf("%s",A[i]);
}
for(i=1;i<=4;i++)
{
for(j=0;j<4;j++)
{
if(A[i][j]=='*')
a[i][j+1]=1;
else
a[i][j+1]=-1;
}
}
for(step=0;step<=16;step++)
{
DFS(1,1,0);
if(flag==1)
break;
}
if(flag==0)
printf("Sorry,I can not help you ..> <..\n");
else
printf("%d\n",step);
}
return 0;
}