题目链接:http://codeforces.com/gym/101755/problem/H
题目分析:先bfs一遍怪兽可以到达的点,再bfs人可以走的地方看可不可以到达终点;
很显然读到 2<=n*m<=200000 时,就不可以用二维数组存图了,不过据说因为数据比较水,可以用vector存图;
vector存图AC代码:
1 /* */ 2 # include <iostream> 3 # include <stdio.h> 4 # include <string.h> 5 # include <string> 6 # include <cmath> 7 # include <climits> 8 # include <cctype> 9 # include <ctime> 10 # include <algorithm> 11 # include <functional> 12 # include <bitset> 13 # include <set> 14 # include <map> 15 # include <deque> 16 # include <queue> 17 # include <stack> 18 # include <vector> 19 using namespace std; 20 21 const int maxn=2e5+7; 22 vector<char>mp[maxn]; 23 vector<int>dis[maxn]; 24 vector<int>vis[maxn]; 25 int n, m; 26 27 struct node 28 { 29 int x, y; 30 int step; 31 }cur, after; 32 33 int dir[4][2]={{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; 34 int sx, sy, fx, fy; 35 36 int check(int x, int y) 37 { 38 if( x>=0 && x<n && y>=0 && y<m ) 39 return 1; 40 return 0; 41 } 42 43 void bfs1(int d) 44 { 45 queue<node>q; 46 int i, j; 47 for( i=0; i<n; i++ ) 48 { 49 for( j=0; j<m; j++ ) 50 { 51 if( mp[i][j]=='M' ) 52 { 53 cur.x = i; 54 cur.y = j; 55 cur.step = 0; 56 q.push(cur); 57 dis[i][j] = 1; 58 } 59 } 60 } 61 62 while( !q.empty() ) 63 { 64 cur = q.front(); 65 q.pop(); 66 for(int i=0; i<4; i++ ) 67 { 68 after.x = cur.x+dir[i][0]; 69 after.y = cur.y+dir[i][1]; 70 after.step = cur.step + 1; 71 72 if( check(after.x, after.y) ) 73 { 74 if( !dis[after.x][after.y] && after.step<=d ) 75 { 76 dis[after.x][after.y] = 1; 77 q.push(after); 78 } 79 } 80 } 81 } 82 } 83 84 void bfs2(int x, int y) 85 { 86 cur.x = x; 87 cur.y = y; 88 cur.step = 0; 89 queue<node>q; 90 q.push(cur); 91 vis[x][y] = 1; 92 if( dis[x][y] ) 93 { 94 printf("-1 "); 95 return ; 96 } 97 while( !q.empty() ) 98 { 99 cur = q.front(); 100 q.pop(); 101 if( mp[cur.x][cur.y]=='F' ) 102 { 103 printf("%d ", cur.step); 104 return ; 105 } 106 for(int i=0; i<4; i++ ) 107 { 108 after.x = cur.x + dir[i][0]; 109 after.y = cur.y + dir[i][1]; 110 after.step = cur.step + 1; 111 if( check(after.x, after.y) ) 112 { 113 if( !dis[after.x][after.y] && !vis[after.x][after.y]) 114 { 115 vis[after.x][after.y] = 1; 116 q.push(after); 117 } 118 } 119 } 120 } 121 printf("-1 "); 122 return ; 123 } 124 int main() 125 { 126 int d, i, j; 127 cin>>n>>m>>d; 128 char s; 129 130 for(i=0; i<n; i++) 131 { 132 mp[i].clear(); 133 vis[i].clear(); 134 dis[i].clear(); 135 } 136 137 for(i=0; i<n; i++ ) 138 { 139 for(j=0; j<m; j++ ) 140 { 141 cin>>s; 142 mp[i].push_back(s); 143 dis[i].push_back(0); 144 vis[i].push_back(0); 145 } 146 } 147 bfs1(d); 148 149 for(i=0; i<n; i++ ) 150 { 151 for( j=0; j<m; j++ ) 152 { 153 if( mp[i][j]=='F' ) 154 { 155 fx = i; 156 fy = j; 157 } 158 if( mp[i][j]=='S' ) 159 { 160 sx = i; 161 sy = j; 162 } 163 } 164 } 165 166 if( dis[fx][fy] ) 167 { 168 printf("-1 "); 169 } 170 else 171 { 172 bfs2(sx, sy); 173 } 174 return 0; 175 }
这道题也让我知道了可以用一位数组存图:
详细的见代码注释:
AC代码:
1 /* */ 2 # include <iostream> 3 # include <stdio.h> 4 # include <string.h> 5 # include <algorithm> 6 # include <cctype> 7 # include <ctime> 8 # include <functional> 9 # include <cmath> 10 # include <bitset> 11 # include <deque> 12 # include <queue> 13 # include <stack> 14 # include <vector> 15 # include <set> 16 # include <map> 17 # include <climits> 18 using namespace std; 19 20 typedef long long LL; 21 const int maxn=1e6+100; 22 int n, m, t; 23 int a[maxn], d; 24 char str[maxn]; 25 bool vis[maxn];///标记是否已经访问过 26 int dis[maxn];///记录步数 27 int dd[maxn];///dd[]为0,说明怪兽到不了,dd不为0说明怪兽可以到此处 28 int cnt, fx, fy, sx, sy; 29 int dir[4][2]={{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; 30 struct node 31 { 32 int x; 33 int y; 34 }g[maxn], cur, after; 35 36 bool check(int a, int b) 37 { 38 if( a>=1 && b>=1 && a<=n && b<=m && !dd[a*m+b] ) 39 return true; 40 return false; 41 } 42 43 void bfs() 44 { 45 queue<node>q; 46 cur.x = sx; 47 cur.y = sy; 48 vis[cur.x*m+cur.y] = 1; 49 q.push(cur); 50 51 while( !q.empty()) 52 { 53 cur = q.front(); 54 q.pop(); 55 for(int i=0; i<4; i++ ) 56 { 57 int xx = cur.x + dir[i][0]; 58 int yy = cur.y + dir[i][1]; 59 60 if( check(xx, yy) && !vis[xx*m+yy]) 61 { 62 dis[xx*m+yy] = dis[cur.x*m+cur.y]+1; 63 vis[xx*m+yy] = 1; 64 after.x = xx; 65 after.y = yy; 66 q.push(after); 67 } 68 } 69 } 70 return ; 71 } 72 73 void bfss()///广搜怪兽可以到达的地方 74 { 75 queue<node>q; 76 for(int i=0; i<cnt; i++ ) 77 q.push(g[i]); 78 79 while( !q.empty() ) 80 { 81 cur=q.front(); 82 q.pop(); 83 84 if( dd[cur.x*m+cur.y]==0 ) 85 continue; 86 87 for(int i=0; i<4; i++ ) 88 { 89 int xx = cur.x + dir[i][0]; 90 int yy = cur.y + dir[i][1]; 91 if( check(xx, yy) ) 92 { 93 after.x = xx; 94 after.y = yy; 95 dd[xx*m+yy] = dd[cur.x*m+cur.y]-1; 96 q.push(after); 97 } 98 } 99 } 100 return ; 101 } 102 103 int main() 104 { 105 while( ~ scanf("%d %d %d", &n, &m, &d) ) 106 { 107 getchar(); 108 for(int i=1; i<=n; i++ ) 109 scanf("%s", &str[i*m+1]);///一维数组存图 110 111 memset(vis, false, sizeof(vis)); 112 memset(dd, 0, sizeof(dd)); 113 memset(dis, 0, sizeof(dis)); 114 115 for(int i=1; i<=n; i++ ) 116 { 117 for(int j=1; j<=m; j++ ) 118 { 119 if( str[i*m+j]=='S' ) 120 { 121 sx = i; 122 sy = j; 123 } 124 125 else if( str[i*m+j]=='F' ) 126 { 127 fx = i; 128 fy = j; 129 } 130 131 else if( str[i*m+j]=='M' ) 132 { 133 dd[i*m+j] = d+1; 134 cur.x = i; 135 cur.y = j; 136 g[cnt++] = cur; 137 } 138 } 139 } 140 141 bfss(); 142 if( dd[sx*m+sy] || dd[fx*m+fy] ) 143 { 144 printf("-1 "); 145 } 146 else 147 { 148 bfs(); 149 if( !vis[fx*m+fy] ) 150 printf("-1 "); 151 else 152 printf("%d ", dis[fx*m+fy]); 153 } 154 } 155 return 0; 156 }