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 }