hdu1010(dfs+剪枝)

http://acm.hdu.edu.cn/showproblem.php?pid=1010

注意,这道题目是要恰好t时间到达,并不是在t时间内到达......

思路:剪枝+dfs

第一个剪枝我们可以想到,当剩下的步数大于剩下的时间的时候,狗是不能走到的;
 
接下来我们来第二个剪枝:
我们把map的奇偶性以01编号:
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,从1走一步一定走到0。
也就是说,如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。
 
也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。
 
注意,在我做题的过程中,剪枝后,还发现超时现象。思考了很久,发现原来是我以前写dfs所带来的缺点......以前从没有注意,以后需要注意。
#include<iostream>
#include<math.h>
using namespace std;
char s[10][10];
int ax,ay,bx,by,n,m,k;
int t[4][2]={1,0,-1,0,0,1,0,-1},vist[10][10],flag;
void dfs(int x,int y,int count)
{
	int i,mx,my;
	if(x==bx&&y==by)
	{
		if(k==count)
			flag=1;
		return;
	}
	if(count>=k)
		return;
	if(s[x][y]!='X')
	{
		for(i=0;i<4;i++)
		{
			mx=x+t[i][0];
			my=y+t[i][1];
			if(s[mx][my]!='X'&&mx>=1&&mx<=n&&my>=1&&my<=m&&!vist[mx][my])
			{
				vist[mx][my]=1;
				dfs(mx,my,count+1);
				vist[mx][my]=0;
				if(flag)                       //注意,在找到了目标之后,就不需要再找!以往编写dfs时,没有注意这点
					return;
			}
		}
	}
}
int main()
{
	while(scanf("%d%d%d",&n,&m,&k)>0&&(n+m+k))
	{
		int i,count;
		for(i=1;i<=n;i++)
		{
			getchar();
			for(int j=1;j<=m;j++)
			{
				scanf("%c",&s[i][j]);
				if(s[i][j]=='S')
				{
					ax=i;
					ay=j;
				}
				if(s[i][j]=='D')
				{
					bx=i;
					by=j;
				}
			}
		}
		getchar();
		memset(vist,0,sizeof(vist));
		if(abs(ax-bx)+abs(ay-by)>k||(ax+bx+ay+by+k)%2==1)            //剪枝
		{
			printf("NO\n");
			continue;
		}
		vist[ax][ay]=1;
		flag=0;
		count=0;
		dfs(ax,ay,count);
		if(flag==1)
			printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

 

 

posted @ 2013-02-08 16:43  紫忆  阅读(5520)  评论(0编辑  收藏  举报