HDOJ 1010 Tempter of the Bone--DFS+奇偶剪枝
題目原文:http://acm.hdu.edu.cn/showproblem.php?pid=1010
題目大意:給出起始位置和終點位置,要求在指定的時間剛好到達終點時間,每移動一步一秒,并且不能返回。
題目分析:
1。起初以為能用BFS做,后來發現,必須在指定的時間內抵達終點才行,BFS無法達到要求。
2。要求在指定時間內到達,唯一想法就是能不能枚舉出所有抵達方案,再在通過檢查時間時間是否吻合,得到結果,這就自然想到了用DFS進行搜索。
3。DFS搜索完成后,提交發現超時,看樣子還得剪枝才行,無奈啊,百度一下。
4。剪枝方法:奇偶剪枝
把map看作
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 需要奇數步
從 0->0 需要偶數步
那么設所在位置 (x,y) 與 目標位置 (dx,dy)
如果abs(x-y)+abs(dx-dy)為偶數,則說明 abs(x-y) 和 abs(dx-dy)的奇偶性相同,需要走偶數步
如果abs(x-y)+abs(dx-dy)為奇數,那么說明 abs(x-y) 和 abs(dx-dy)的奇偶性不同,需要走奇數步
理解為 abs(si-sj)+abs(di-dj) 的奇偶性就確定了所需要的步數的奇偶性?。?/p>
而 (ti-setp)表示剩下還需要走的步數,由于題目要求要在 ti時 恰好到達,那么 (ti-step) 與 abs(x-y)+abs(dx-dy) 的奇偶性必須相同
因此 temp=ti-step-abs(dx-x)-abs(dy-y) 必然為偶數!
5。最后一點:整個圖的可以移動步數應該大于指定的時間
#include "iostream" #include <math.h> using namespace std; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; int n,m; char a[7][7]; int sx,sy,dx,dy; int ti,flag; void DfsSerch(int x,int y,int step) { ///////////////////////////////////// int temp; temp=ti-step-abs(dx-x)-abs(dy-y); if (temp<0||temp%2==1) return; //////////////////////////////////// int tx,ty; for(int i=0;i<4;i++) //方向探索 { tx=x+dir[i][0]; ty=y+dir[i][1]; if (a[tx][ty]=='D'&&step==ti-1) { flag=1; return ; } if(a[tx][ty]=='.'&&(tx>=0&&tx<n) &&(ty>=0&&ty<m)) { a[tx][ty]='X'; //標記訪問 DfsSerch(tx,ty,step+1); a[tx][ty]='.'; //回溯取消標記 if(flag==1) return;//找到直接返回 } } } int main() { while (cin>>n>>m>>ti&&n!=0||m!=0||ti!=0) { /////////////////////////////////////// //輸入數據 int wall=0; for (int i=0;i<n;i++) for(int j=0;j<m;j++) { cin>>a[i][j]; if(a[i][j]=='S') { sx=i; sy=j; } if (a[i][j]=='D') { dx=i; dy=j; } if (a[i][j]=='X') { wall++; } }//for-for ///////////////////////////////////// flag=0; if (n*m-wall<=ti) { cout<<"NO"<<endl; continue; } DfsSerch(sx,sy,0); if(flag==1) cout<<"YES"<<endl; else cout<<"NO"<<endl; } return 0; }
posted on 2010-04-26 17:20 Geek.tan 閱讀(1956) 評論(0) 編輯 收藏 引用 所屬分類: ACM解題報告