题目链接:http://acm.nbut.cn/Problem/view.xhtml?id=1264
类型:DFS
这题是放假时候想了好久才A的,其实这题就是个普通的搜索题,只要把题目理解好了就OK了
题目大意:题目输入4*4的图形,里面只包含*与#。每次操作可以将该坐标的上下左右及坐标中心转变为另一图形,比如翻转前 # 翻转后变为 *- #*# *#*
# * - 你所需要做的就是判断原图形,经过多次变换后最后是否可以变为全*或者全#。
- 题解:首先我们需要定义几个函数
- 第一个:翻转函数 turn(int x,int y),将指定坐标按规则翻转;
我再输入的时候将*转为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];
}
- 第二个:判断函数 judge(void),判断是否满足全*或者全#;
这里我通过每个位置与首位置比较,如果出现不同的则说明,没有胜利
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;
}
- 第三个:深搜函数DFS(int i,int j,int count)
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;
}