主要是深搜和奇偶型剪枝
减枝原理:
http://baike.baidu.com/view/7789287.htm?fr=aladdin;
0
|
1
|
0
|
1
| 0 |
1 |
0
|
1
|
0
| 1 |
0
|
1
| 0 | 1 | 0 |
1
| 0 | 1 | 0 | 1 |
0
|
1
|
0
|
1
|
0
|
我们现假设从 0 开始走,则不难证明,
从任意 0 走到任意 1 始终是奇数步;
从任意 0 走到任意 0 始终是偶数步;
sum= t + extra ( extra>=0 ) //SUM为要绕过障碍的所需要的总时间,T为最小步数,EXTRA必为偶数
#include<iostream>
using namespace std;
int n,m,k,endx,endy;
int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}},book[9][9];//移动的方向
int flag;
char a[9][9];
void dfs(int x,int y,int time)
{
int i;
if(time>k)
return;
if((k-time)<(endx-x+endy-y))//最小步数原理
return ;
if((k-time-(endx-x+endy-y))%2!=0)//奇偶性减枝,这个是关键
return;
if(x==endx&&y==endy&&flag==0)//刚开始少了个=,弄了半个小时,蛋疼!!
{
if(time==k)
{
cout<<"YES"<<endl;
flag=1;
}
return ;
}
if(flag==1)
return ;
// book[x][y]=1;
int fangx,fangy;
for(i=0;i<4;i++)
{
fangx=x+mov[i][0];
fangy=y+mov[i][1];
if(fangx>=1&&fangx<=n&&fangy>=1&&fangy<=m&&book[fangx][fangy]==0&&a[fangx][fangy]!='X')
{
book[fangx][fangy]=1;
dfs(fangx,fangy,time+1);
book[fangx][fangy]=0;
}
}
book[x][y]=0;
}
int main()
{
while(cin>>n>>m>>k,n,m,k)
{
memset(book,0,sizeof(book));
flag=0;
int i,j,startx,starty;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='S')
{
startx=i;
starty=j;
}
if(a[i][j]=='D')
{
endx=i;
endy=j;
}
}
}
book[startx][starty]=1;
if(k<(endx-startx+endy-starty))
cout<<"NO"<<endl;
else
{
dfs(startx,starty,0);
if(flag==0)
cout<<"NO"<<endl;
}
}
}