http://acm.hdu.edu.cn/showproblem.php?pid=1010
这个题一开始是用的bfs,可能是我的代码不够优化吧,一直TLE
但是bfs做时应注意一个条件,bfs求得是最短路径等最优化问题,假如找到出口,但是这时需判断当前所用时间和规定时间是否相等,不相等,应剪枝。
用dfs时,应做一下剪枝:
t表示规定时间,mindis表示当前位置到达出口的最短距离,steps表示从起点到当前位置已走得步数。num表示可走的点数。
1)steps>t时,即没在规定的时间准时到达出口,应剪枝。
2)num<t时,应剪枝。
3)奇偶剪枝:当(t-steps-mindis)&1==1时,即当前所剩规定步数与当前位置到达出口的最短距离的差是奇数时,应剪枝。
4)路径剪枝:当t-steps>mindis时,即当前所剩规定时间不够时,应剪枝。
#include<bits/stdc++.h>
using namespace std;
const int N=10;
int flag,sx,sy,ex,ey,num;
int n,m,t;
char g[N][N];
int used[N][N];
int dir[4][2]={1,0,0,-1,-1,0,0,1};
void dfs(int x,int y,int steps)
{
int k,a,b;
if(flag==1) return;
if(x==ex&&y==ey&&steps==t)
{
flag=1;
return ;
}
int mindis=abs(x-ex)+abs(y-ey);
if(mindis>t-steps||(t-steps-mindis)&1) return;
// if(steps>t) return ;这句话没必要写,因为上一句已经包含这种情况
for(k=0;k<4;k++)
{
a=x+dir[k][0];
b=y+dir[k][1];
if(a>=0&&a<n&&b>=0&&b<m&&!used[a][b]&&g[a][b]!='X')
{
used[a][b]=1;
dfs(a,b,steps+1);
used[a][b]=0;
}
}
}
int main()
{
int i,j;
while(~scanf("%d%d%d",&n,&m,&t),n,m,t)
{
num=0;
for(i=0;i<n;i++)
{
scanf("%s",g[i]);
for(j=0;j<m;j++)
{
if(g[i][j]=='S') sx=i,sy=j;
if(g[i][j]=='D') ex=i,ey=j;
if(g[i][j]=='X') num++;
}
}
if(n*m-num-1<t)
{
printf("NO\n");
continue;
}
flag=0;
memset(used,0,sizeof(used));
used[sx][sy]=1;
dfs(sx,sy,0);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}