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