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;
}

 

 

    原文作者:紫忆
    原文地址: https://www.cnblogs.com/ziyi--caolu/archive/2013/02/08/2909325.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞