1.首先这道题用的是深搜加剪枝。
2.深搜其实就是一个递归,原理略去,在代码上的实现是分成几步:
第一:确定终止条件。
第二,确定想四个方向前进的for循环。
第三,在for循环里递归调用。
注意,在前进时要标记已经走过的路,这里直接用的吧走过的路变成墙来做的,比较方便。
3.剪枝用了两次,一次在主函数先总得确定是不是迷宫上有那么多可以走的空格。另一次是递归是奇偶剪枝(因为从一个角到对角总是会经过两步,一个x,一个y)。
下面是代码:
#include <iostream>
using namespace std;
char maze[7][7];
int ne[4][2] = {1,0,0,-1,-1,0,0,1};
int n,m,t;
int sx,sy,dx,dy,wall;
bool dfs(int x,int y, int step)
{
int temp = t-step-abs(dx-x)-abs(dy-y);
if(temp<0||temp%2==1)
{
return false;
}
for ( int i = 0; i < 4; i++ )
{
int nextX = x+ne[i][0];
int nextY = y+ne[i][1];
if(t==step+1&&maze[nextX][nextY]=='D')
{
return true;
}
if(nextX>=0&&nextX<n&&nextY>=0&&nextY<m)
{
//下面这个地方不能用不等于‘X',不知道为什么。
if(maze[nextX][nextY]=='.')
{
maze[nextX][nextY]='X';
if(!dfs(nextX,nextY,step+1))
{
maze[nextX][nextY]='.';
}else
return true;
}
}
}
return false;
}
int main()
{
while(cin>>n>>m>>t&&!(n==0&&m==0&&t==0))
{
wall=0;
for (int i = 0; i < n; i++)
{
for(int j = 0; j < m; j++ )
{
cin>>maze[i][j];
if(maze[i][j]=='S')
{
sx = i;
sy= j;
}
if(maze[i][j]=='D')
{
dx=i;
dy=j;
}
if(maze[i][j]=='X')
{
wall++;
}
}
}
if(n*m-wall<=t)
{
cout << "NO"<<endl;
continue;
}
bool flag = dfs(sx,sy,0);
if(flag)
{
cout <<"YES"<<endl;
}else{
cout <<"NO"<<endl;
}
}
return 0;
}
只是要注意,如果在判断的时候不用等于号,就总是超时。不知道为什么。这导致判断到没到出口只能放在for循环里而不能放到dfs函数的开头。