奇偶剪枝:
把矩阵标记成如下形式:
0,1,0,1,0
1,0,1,0,1
0,1,0,1,0
1,0,1,0,1
很明显,如果起点在0 而终点在1 那显然 要经过奇数步才能从起点走到终点,依次类推,奇偶相同的偶数步,奇偶不同的奇数步
奇偶剪枝:读入的时候起点记为(Si,Sj) 终点记为(Di,Dj) 判断(Si+Sj) 和 (Di+Dj) 的奇偶性 如果与要求步数奇偶性不同就cut
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
const int M = 11;
int n,m,T,ex,ey,vis[M][M],flag;
char g[M][M];
typedef struct{
int x2;
int y2;
}MOVE;
MOVE Move[4]={{-1,0},{1,0},{0,-1},{0,1}};
struct Node{
int x;
int y;
int dist;
Node(int x1,int y1,int d):x(x1),y(y1),dist(d)
{
}
};
bool check(int a,int b)
{
if(a>=0&&a<n&&b>=0&&b<m&&g[a][b]!='X'&&!vis[a][b])
return true;
else
return false;
}
void dfs(int x,int y,int cur)
{
if(cur>T||flag) return; //cut
if(cur==T&&x==ex&&y==ey)
{
flag=1;
return;
}
int a,b;
for(int i=0;i<4;i++)
{
a=x+Move[i].x2;
b=y+Move[i].y2;
if(check(a,b))
{
vis[a][b]=1;
dfs(a,b,cur+1);
vis[a][b]=0; //回溯
}
}
}
int main()
{
int i,j,sx,sy,k1,k2;
while(cin>>n>>m>>T&&(n+m+T))
{
flag=0;
memset(vis,0,sizeof(vis));
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cin>>g[i][j];
if(g[i][j]=='S')
{
sx=i;
sy=j;
}
if(g[i][j]=='D')
{
ex=i;
ey=j;
}
}
}
k1=(sx+sy)%2; //算出起始点的 奇偶性
k2=(ex+ey)%2; //0->1 奇数步 0->0偶数步 证明 0->0 移动相邻的0:2步 0反复移动到相邻的0 2n步
if(((k1+k2)%2==0&&T%2)||((k1+k2)%2&&T%2==0))//0->1 移动到相邻的1 1步 1反复移动到相邻的1 2n步 所以2n+1步
{
flag=0;
}
else
{
vis[sx][sy]=1;
dfs(sx,sy,0);
}
if(flag)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}