hdu 1010 Tempter of the Bone
这是一道关于迷宫的搜索题,注意看懂题意:必须在time=T的时候门才开,这个时候必须准时到达door才能survive,既不能早了,也不能晚了,有一个细节用到了奇偶剪枝原理
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
using namespace std;
int N,M,T,OK;
int startx,starty,endx,endy;
char maze[8][8];
int mark[8][8];
int X[4]={1,-1,0,0};
int Y[4]={0,0,1,-1};
void DFS(int x,int y ,int primetime)
{
if(OK==1)return ;
if(primetime==T)
{
if(x==endx&&y==endy)
{
OK=1;
}
return ;
}
int left=abs(x-endx)+abs(y-endy);
if((primetime+left)>T)return ;
if(left%2!=(T-primetime)%2)return ;//奇偶剪枝
int i;
for(i=0;i<4;i++)
{
int newx=x,newy=y;
newx+=X[i];
newy+=Y[i];
if(maze[newx][newy]!='X'&& mark[newx][newy]==0)
{
mark[newx][newy]=1;
DFS(newx,newy,primetime+1);
mark[newx][newy]=0;
}
}
}
int main()
{
int i,j;
setbuf(stdout,NULL);
while(scanf("%d %d %d",&N,&M,&T)!=EOF)
{
if(N==0&&M==0&&T==0)break;
memset(maze,'X',sizeof(maze));
memset(mark,0,sizeof(mark));
int walls=0;
for(i=1;i<=N;i++)
{
for(j=1;j<=M;j++)
{
cin>>maze[i][j];
if(maze[i][j]=='S')
{
startx=i;
starty=j;
}
if(maze[i][j]=='D')
{
endx=i;
endy=j;
}
if(maze[i][j]=='X')walls++;
}
}
OK=0;
if(N*M-walls<T){printf("NO\n");continue;}
mark[startx][starty]=1;
DFS(startx,starty,0);
if(OK==1)
{
printf("YES\n");
continue;
}
printf("NO\n");
}
return 0;
}
剪枝方法:奇偶剪枝
把map看作
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从 0->1 需要奇数步
从 0->0 需要偶数步
那么设所在位置 (x,y) 与 目标位置 (dx,dy)
如果abs(x-y)+abs(dx-dy)为偶数,则说明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶数步
如果abs(x-y)+abs(dx-dy)为奇数,那么说明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇数步
理解为 abs(si-sj)+abs(di-dj) 的奇偶性就确定了所需要的步数的奇偶性!!
而 (ti-setp)表示剩下还需要走的步数,由于题目要求要在 ti时 恰好到达,那么 (ti-step) 与 abs(x-y)+abs(dx-dy) 的奇偶性必须相同
因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然为偶数!
posted on 2011-07-19 13:31 lonelycatcher 阅读(190) 评论(0) 收藏 举报
浙公网安备 33010602011771号