奇偶是数据结构的搜索中,剪枝的一种特殊小技巧。
现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
s
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
—
|
—
|
—
|
e
|
如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
s
|
—
|
—
|
—
|
|
|
—
|
—
|
+
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
+
|
—
|
—
|
—
|
e
|
如图,为一般情况下非
最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);
故,若t-[abs(ex-sx)+abs(ey-sy)]结果为非偶数(奇数),则无法在t步恰好到达;
返回,false;
反之亦反。
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
char map[8][8];
int f[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
struct node
{
int x,y;
}S,D;
int step,n,m,flag;
void dfs(node p,int t)
{
node q;
int k,s;
if(flag) return;
if(p.x==D.x&&p.y==D.y&&t==step)
{
flag=1;
return;
}
for(int i=0;i<4;i++)
{
k=p.x+f[i][0];
s=p.y+f[i][1];
if(k>=0&&k<n&&s>=0&&s<m&&map[k][s]!='X')
{
map[k][s]='X';
q.x=k;q.y=s;
t++;
dfs(q,t);
map[k][s]='.';
t--;
}
}
}
int main()
{
int t;
while(~scanf("%d%d%d",&n,&m,&step),n+m+step)
{
flag=0;
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
if(map[i][j]=='S')
{
S.x=i;
S.y=j;
map[i][j]='X';
}
if(map[i][j]=='D')
{
D.x=i;
D.y=j;
}
}
t=abs(S.x-D.x)+abs(S.y-D.y);
if(step<t||(step-t)%2) //(step-t)%2是奇偶剪枝
{
printf("NO\n");continue;
}
dfs(S,0);
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}