题目大意:一个dog想吃bone ,但是有bone的地方是一个陷阱,然后dog要在恰好是n的时间到达门口,问dog能逃生吗?
这个题目本来第一次看的时候以为很简单,但是自己还是没写出来啊,过了很久看别人的题解,才知道这个题原来有很多的地方可以剪枝。。。。
其中比较特殊的两个剪枝的方法:
1.最短路径与时间比较。
2.奇偶剪枝,dog要是到达与他此时位置奇偶性相同的位置需要偶数步,如果是到达与他奇偶性不同的地方需要奇数步,基此剪枝。。。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=10;
char str[maxn][maxn];
int row,col,n,sr,sc,er,ec;
int flag;
int RR[]={0,1,0,-1};
int CC[]={1,0,-1,0};
int vis[maxn][maxn];
void DFS(int x,int y,int num)
{
if(x==er&&y==ec)
{
if(num==n)
flag=1;
return;
}
if(num>=n) return;
if(str[x][y]!='X')
for(int i=0;i<4;i++)
{
int mr=x+RR[i];
int mc=y+CC[i];
if(mr>=0&&mr<row&&mc>=0&&mc<col&&str[mr][mc]!='X'&&!vis[mr][mc])
{
vis[mr][mc]=1;
DFS(mr,mc,num+1);
vis[mr][mc]=0;//不要忘记在恢复状态
if(flag) return;
}
}
}
int main()
{
while(scanf("%d%d%d",&row,&col,&n)!=EOF)
{
if(row==0&&col==0&&n==0) break;
memset(str,0,sizeof(str));
memset(vis,0,sizeof(vis));
flag=0;
for(int i=0;i<row;i++)
scanf("%s",str[i]);
for(int i=0;i<row;i++)
{
for(int j=0;j<col;j++)
{
if(str[i][j]=='S')
{
sr=i;
sc=j;
}
if(str[i][j]=='D')
{
er=i;
ec=j;
}
}
}
if(((abs(er-sr)+abs(sc-ec))>n)||((er+sr+sc+ec+n)%2))//两个剪枝方法
{
printf("NO\n");
continue;
}
flag=0;
int cnt=0;
vis[sr][sc]=1;
DFS(sr,sc,cnt);
if(flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}