4 4 5 S.X. ..X. ..XD .... 3 4 5 S.X. ..X. ...D 0 0 0
NO YES
最開始看見這題直接看了樣例,覺得就是詢問t時間內能不能走出去,直接寫了個BFS過了樣例,提交上去WA了=7=,事實證實仍是不能偷懶。
題意就是S當前位置,D是門,X是牆,問你能不能恰好在t時刻走到門D那裏。
而後就是套DFS,本地測試炸棧,就想到了剪枝一下
1 int tp = t - step - abs(dx - x) - abs(dy - y); 2 if(tp < 0 || tp % 2 == 1) 3 return ;
這就是剪枝代碼,dx和dy表明門的座標,x、y爲當前座標,step表示以及走了的步數。ios
當剩餘時間走不到門時結束,這個好理解,難理解的是爲何爲奇數是也結束。app
由於從s每走一步,必定是x或y進行+1或者-1,要使得t時間恰好走到門d。less
最短路徑m = |dx - x| + |dy - y|;測試
兩種狀況,t < m時,確定沒法到達;this
t >= m時,從S到D的行走步驟兩部分組成,step = t = m + x;(m爲最段路徑,x爲附加步數);spa
這x = t - m步必定是從最短路徑中的某一步走出去,再回到最短路徑的步數,並且兩者必定是相等的。code
如圖,最短路徑爲橘色所示,附加路徑爲藍色所示,把藍色路徑分爲走出和走回兩部分,不管你怎麼添加附加路徑,這兩部分必定是相等的步數。blog
因此,x必定得爲偶數才能保證從S恰好走到D。three
而在剪枝中,tp就是咱們的x,只有當tp爲偶數時,才繼續行走。ip
完整代碼:
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <sstream> 6 #include <iomanip> 7 #include <map> 8 #include <stack> 9 #include <deque> 10 #include <queue> 11 #include <vector> 12 #include <set> 13 #include <list> 14 #include <cstring> 15 #include <cctype> 16 #include <algorithm> 17 #include <iterator> 18 #include <cmath> 19 #include <bitset> 20 #include <ctime> 21 #include <fstream> 22 #include <limits.h> 23 #include <numeric> 24 25 using namespace std; 26 27 #define F first 28 #define S second 29 #define mian main 30 #define ture true 31 32 #define MAXN 1000000+5 33 #define MOD 1000000007 34 #define PI (acos(-1.0)) 35 #define EPS 1e-6 36 #define MMT(s) memset(s, 0, sizeof s) 37 typedef unsigned long long ull; 38 typedef long long ll; 39 typedef double db; 40 typedef long double ldb; 41 typedef stringstream sstm; 42 const int INF = 0x3f3f3f3f; 43 44 int n,m,t,flag,wall; 45 int sx,sy,dx,dy; 46 char mp[8][8]; 47 int vis[8][8]; 48 int fx[4][2] = {1,0,-1,0,0,1,0,-1}; 49 50 bool check(int x,int y){ 51 if(!vis[x][y] && mp[x][y] != 'X' && x >= 0 && y >= 0 && x < n && y < m){ 52 return true; 53 } 54 return false; 55 } 56 57 void dfs(int x,int y,int step){ 58 if(flag) 59 return ; 60 if(x == dx && y== dy && step == t){ 61 flag = 1; 62 return ; 63 } 64 65 int tp = t - step - abs(dx - x) - abs(dy - y); 66 if(tp < 0 || tp % 2 == 1) 67 return ; 68 69 for(int i = 0; i < 4; i++){ 70 int next_x = x + fx[i][0]; 71 int next_y = y + fx[i][1]; 72 if(check(next_x,next_y)){ 73 vis[next_x][next_y] = 1; 74 dfs(next_x,next_y,step+1); 75 if(flag) 76 return ; 77 vis[next_x][next_y] = 0; 78 } 79 } 80 return ; 81 } 82 83 int main(){ 84 ios_base::sync_with_stdio(false); 85 cout.tie(0); 86 cin.tie(0); 87 while(cin>>n>>m>>t && n && m && t){ 88 fill(vis[0],vis[0]+64,0); 89 MMT(mp); 90 flag = 0, wall = 0; 91 for(int i = 0; i < n; i++) 92 cin>>mp[i]; 93 for(int i = 0; i < n; i++){ 94 for(int j = 0; j < m; j++){ 95 if(mp[i][j] == 'S') 96 sx = i,sy = j; 97 if(mp[i][j] == 'D') 98 dx = i,dy = j; 99 if(mp[i][j] == 'X') 100 wall++; 101 } 102 } 103 if(t < abs(dx - sx) + abs(dy - sy) || t > n*m - wall - 1){ 104 cout << "NO" << endl; 105 continue; 106 } 107 vis[sx][sy] = 1; 108 dfs(sx,sy,0); 109 if(flag) 110 cout << "YES" << endl; 111 else 112 cout << "NO" << endl; 113 } 114 115 return 0; 116 }