Tempter of the Bone
直接上中文了
Descriptions:
暑假的時候,小明和朋友去迷宮中尋寶。然而,當他拿到寶貝時,迷宮開始劇烈震動,他感到地面正在下沉,他們意識到這是一個陷阱!他們想盡一切辦法逃出去。
迷宮是一個大小為 N*M 的長方形,迷宮中有一扇門。一開始,門是關着的,他會在第 t 秒的時間打開。因為,小明和朋友必須在第 t 秒到大門口。每一秒,他都可以向上下左右四個方向移動一個點。一旦他移動了,他剛才所在的點就消失,(這意味着他不能回到他已經走過的點)。他不能在一個點上停留超過一秒,並且不能走障礙點。小明和朋友能安全的逃出嗎?
Input
輸入由多個測試用例組成。每個測試用例的第一行包含三個整數 N、M 和 T ( 1 < N , M < 7 ; 0 < T < 50 ),分別表示迷宮的大小和門打開的時間。接下來的N行給出迷宮布局,每一行包含M個字符。下列字母分別表示:
"X": 一堵牆,小明和朋友不能在上面停留
"S": 起點
"D": 門
".": 可以走的點
輸入以 3 個 0 時結束。這個測試用例不需要處理。
Output
對於每組樣例輸出一行。
如果小明能夠安全逃出,輸出 "YES" ,否則輸出 "NO"。
Sample Input
4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
Sample Output
NO YES
題目鏈接:
https://vjudge.net/problem/HDU-1010
一開始沒讀清題 上去就bfs WA 了
然后想用bfs做,錯了好多次發現不行,bfs更加適用於求最短路徑等等最優化的題目由於這道題目時間給定,而到目的的所用卻不一定。即:可能有多種到達目的地的方法,不同方法需要的時間不同。並不要求是最短時間。所以bfs不合適
比如:
4 5 5
X X S . .
X X . . X
X . . . X
X . D . X
從S到D其實有很多條路的,最短3步,也可以有其他很多走法,不同走法需要的時間不同,用bfs求的是最短時間,如果題目時間是5呢?BFS答案是錯誤的,但是其實可以走到的。
然后dfs 結果超時 需要剪枝
奇偶剪枝:
s | ||||
| | ||||
| | ||||
| | ||||
+ | — | — | — | e |
s | — | — | — | |
— | — | + | ||
| | + | |||
| | ||||
+ | — | — | — | e |
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #include <sstream> #define mod 1000000007 #define eps 1e-6 #define ll long long #define INF 0x3f3f3f3f #define MEM(x,y) memset(x,y,sizeof(x)) #define Maxn 10 using namespace std; int T,n,m,steps; int ex,ey,sx,sy;; char mp[Maxn][Maxn];//原始地圖 int vis[Maxn][Maxn];//記錄人是否走過 int dt[][2]= {{1,0},{-1,0},{0,1},{0,-1}};//四個方向 int dfs(int x,int y,int step)//當前坐標 當前步數 { if(x==ex&&y==ey&&step==steps)//滿足條件,成功 return 1; for(int i=0; i<4; i++)//四個方向 { int tx=x+dt[i][0]; int ty=y+dt[i][1]; if(tx>=0&&tx<n&&ty>=0&&ty<m&&!vis[tx][ty]&&mp[tx][ty]!='X')//判斷條件 { vis[tx][ty]=1; if(dfs(tx,ty,step+1))//繼續搜索 return 1; vis[tx][ty]=0;//回溯 } } return 0; } int main() { while(cin>>n>>m>>steps,n+m+steps) { MEM(vis,0);//初始化 for(int i=0; i<n; i++) for(int j=0; j<m; j++) { cin>>mp[i][j]; if(mp[i][j]=='S')//起點 { sx=i,sy=j; vis[sx][sy]=1;//標記 } if(mp[i][j]=='D')//終點 ex=i,ey=j; } if((abs(ex-sx)+abs(ey-sy))%2!=steps%2)//剪枝,不然超時 cout<<"NO"<<endl; else { if(dfs(sx,sy,0)) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } }