上链接:杭电1010
题目大意:
输入一个n*m的地图,有可以走的和不能走的石头,看t步能不能走到出口
思路:
一个深搜,不过第一次没过,后来排除特殊情况,并且进行了剪枝,就过了
贴代码:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
bool flag;
int n, m, t;
int sx, sy, fx, fy, Xnum;
char map[7][7];
void dfs(int x, int y, int time)
{
if(x==fx && y==fy && time==t)
{
flag = true;
return ;
}
int c = (t-time)-abs(x-fx)-abs(y-fy);
if(c<0 || c%2==1)
{
flag = false;
return ;
}
if(x-1>=0 && map[x-1][y]!='X')
{
map[x-1][y] = 'X';
dfs(x-1, y, time+1);
map[x-1][y] = '.';
}
if(flag) return ;
if(x+1<n && map[x+1][y]!='X')
{
map[x+1][y] = 'X';
dfs(x+1, y, time+1);
map[x+1][y] = '.';
}
if(flag) return ;
if(y-1>=0 && map[x][y-1]!='X')
{
map[x][y-1] = 'X';
dfs(x, y-1, time+1);
map[x][y-1] = '.';
}
if(flag) return ;
if(y+1<m && map[x][y+1]!='X')
{
map[x][y+1] = 'X';
dfs(x, y+1, time+1);
map[x][y+1] = '.';
}
if(flag) return ;
}
int main()
{
while(cin>>n>>m>>t && !(n==0 && m==0 && t==0))
{
flag = false;
Xnum = 0;
for(int i=0; i<n; ++i)
{
for(int j=0; j<m; ++j)
{
cin>>map[i][j];
if(map[i][j] == 'S')
{
sx = i;
sy = j;
map[i][j] = 'X';
}
else if(map[i][j] == 'D')
{
fx = i;
fy = j;
}
else if(map[i][j] == 'X')
++Xnum;
}
}
if(n*m-Xnum>=t) dfs(sx, sy, 0);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}
注意事项:
这个题容易超时,需要进行剪枝工作:
19行处需要进行奇偶剪枝,因为当剩余步数为奇数的时候将会不符合条件