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