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;

}

 

 

你可能感兴趣的:(HDU)