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

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM