传送门:hdu1010
因为是在规定的时间点到达目的地所以必须用深搜。。
自己写的深搜用尽浑身剪枝方法才勉强压线950ms过。。搜一发题解才发现对于这种确定时间到达的有一种很奇妙的剪枝方法,奇偶剪枝。。我就直接转了吧。。
附上我自己写的代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
int n,m,T,flag=0;
int sc,sr,ec,er;
using namespace std;
char map[10][10];
int book[10][10];
int go[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(int r,int c,int time)
{
if(flag)
return ;
if(time==T)
{
if(r==er&&c==ec)
{
flag=1;
printf("YES\n");
}
return ;
}
if(r==er&&c==ec&&time!=T)
return ;
if(abs(er-r)+abs(ec-c)+time>T)//剩下的最短路程加上已用时间若大于给定时间就返回
return ;
for(int i=0;i<4;i++)
{
int nr=r+go[i][0],nc=c+go[i][1];
if(!book[nr][nc]&&nr<n&&nc<m&&nr>=0&&nc>=0&&(map[nr][nc]=='.'||map[nr][nc]=='D'))
{
book[nr][nc]=1;
dfs(nr,nc,time+1);
book[nr][nc]=0;
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&T)&&(n+m+T))
{
int cnt=0;
getchar();
flag=0;
memset(book,0,sizeof(book));
memset(map,0,sizeof(map));
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='.')
cnt++;
if(map[i][j]=='S')
{
sr=i;
sc=j;
}
if(map[i][j]=='D')
{
er=i;
ec=j;
}
}
getchar();
}
if(abs(er-sr)+abs(ec-sc)>T||cnt+1<T)//最短路程大于给定时间或者地图中可以呆的时间(由于每个点只能呆一单位时间)
{<span style="white-space:pre"> </span>//小于给定时间就直接输出no
printf("NO\n");
continue;
}
book[sr][sc]=1;
dfs(sr,sc,0);
if(!flag)
printf("NO\n");
}
}