您的位置:首页 > 其它

hdu1010

2016-04-18 21:14 239 查看
奇偶剪枝:

是数据结构的搜索中,剪枝的一种特殊小技巧。

现假设起点为(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;

反之亦反。

上面借鉴了! http://www.cnblogs.com/zhourongqing/archive/2012/04/28/2475684.html 感谢!!!

#include<iostream>
#include<math.h>
using namespace std;
int f,n,m,t,sx,sy,dx,dy;
char a[10][10];
int d[4][2]={0,1,1,0,0,-1,-1,0};//代表四个方向!
void dfs(int x,int y,int t)
{
if(f==1) return ;
if(t<abs(dx-x)+abs(dy-y)||(t-abs(dx-x)-abs(dy-y))%2) return ;
//剪枝,如果剩余时间还大于两点的路径;或剩余时间减去两点的值是偶数的话就可以继续搜索;
else if(t==0)
{  // 如果时间等于零了,讨论;
if(dx==x&&dy==y)
{
f=1;return ;
}
else
return ;
}
else  //对四个方向进行深搜;
{
for(int i=0;i<4;i++)
{
int xx=x+d[i][0];int yy=y+d[i][1];
if((xx>0&&xx<=n&&yy>0&&yy<=m)&&(a[xx][yy]=='.'||a[xx][yy]=='D'))
//判断是不是墙!
{
a[xx][yy]='X';
dfs(xx,yy,t-1);
a[xx][yy]='.';
}
}
}
return ;
}
int main()
{
int i,j;
while(cin>>n>>m>>t&&(n||m||t))
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
cin>>a[i][j];
if(a[i][j]=='S')
{
sx=i;sy=j;
}
if(a[i][j]=='D')
{
dx=i;dy=j;
}
}
f=0;
dfs(sx,sy,t);
if(f==1)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: