题目链接:https://codeforces.com/contest/1105/problem/D
题意:p 个人在 n * m 的地图上扩展自己的城堡范围,每次最多走 a_i 步(曼哈顿距离),按 1 ~ p 的顺序,问最后每个人占领的点的数量。
题解:用一个队列维护当前起点,用另一个队列模拟当前起点走 a_i 步可以到达的全部点。(60 ~ 63行关键代码,多源bfs,不可分开跑)
数据:
4 3 2
2 1
1..
1..
..2
...
output:10 2
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #define pii pair<int,int> 9 #define pb push_back 10 #define lowbit(x) ((x)&(-x)) 11 const int INF = 0x3f3f3f3f; 12 const double eps = 1e-6; 13 const int maxn = 1e3 + 10; 14 const int maxm = 1e6 + 10; 15 const ll mod = 1e9 + 7; 16 17 int n,m,p; 18 char s[maxn][maxn]; 19 int a[15],vis[maxn][maxn]; 20 int dx[4] = {-1,0,0,1}; 21 int dy[4] = {0,-1,1,0}; 22 23 struct node { 24 int x,y,d; 25 }; 26 27 bool judge(int x,int y) { 28 if(x <= 0 || x > n || y <= 0 || y > m || s[x][y] == '#') return false; 29 return true; 30 } 31 32 int main() { 33 #ifdef local 34 freopen("data.txt", "r", stdin); 35 // freopen("data.txt", "w", stdout); 36 #endif 37 scanf("%d%d%d",&n,&m,&p); 38 for(int i = 1; i <= p; i++) scanf("%d",&a[i]); 39 for(int i = 1; i <= n; i++) { 40 scanf("%s",s[i] + 1); 41 for(int j = 1; j <= m; j++) vis[i][j] = -1; 42 } 43 queue<pii>q; 44 for(int k = 1; k <= p; k++) { 45 for(int i = 1; i <= n; i++) { 46 for(int j = 1; j <= m; j++) { 47 if(s[i][j] - '0' == k) { 48 q.push(mp(i,j)); 49 vis[i][j] = k; 50 } 51 } 52 } 53 } 54 while(!q.empty()) { 55 pii now = q.front(); 56 q.pop(); 57 int x = now.first, y = now.second; 58 queue<node>q1; 59 q1.push({x,y,a[vis[x][y]]}); 60 while(!q.empty() && vis[q.front().first][q.front().second] == vis[x][y]) { 61 q1.push({q.front().first,q.front().second,a[vis[x][y]]}); 62 q.pop(); 63 } 64 while(!q1.empty()) { 65 node hh = q1.front(); 66 q1.pop(); 67 if(hh.d <= 0) continue; 68 for(int i = 0; i < 4; i++) { 69 int nx = hh.x + dx[i], ny = hh.y + dy[i], d = hh.d; 70 if(judge(nx,ny) && vis[nx][ny] == -1) { 71 vis[nx][ny] = vis[x][y]; 72 q1.push({nx,ny,d - 1}); 73 q.push(mp(nx,ny)); 74 } 75 } 76 } 77 } 78 int ans[15] = {0}; 79 for(int i = 1; i <= n; i++) { 80 for(int j = 1; j <= m; j++) { 81 if(vis[i][j] != -1) ans[vis[i][j]]++; 82 } 83 } 84 for(int i = 1; i <= p; i++) printf("%d ",ans[i]); 85 return 0; 86 }