Codeforces Round #533 (Div. 2) D. Kilani and the Game(BFS)

时间:2023-03-09 01:28:42
Codeforces Round #533 (Div. 2) D. Kilani and the Game(BFS)

题目链接: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

 #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define mst(a,b) memset((a),(b),sizeof(a))
#define mp(a,b) make_pair(a,b)
#define pi acos(-1)
#define pii pair<int,int>
#define pb push_back
#define lowbit(x) ((x)&(-x))
const int INF = 0x3f3f3f3f;
const double eps = 1e-;
const int maxn = 1e3 + ;
const int maxm = 1e6 + ;
const ll mod = 1e9 + ; int n,m,p;
char s[maxn][maxn];
int a[],vis[maxn][maxn];
int dx[] = {-,,,};
int dy[] = {,-,,}; struct node {
int x,y,d;
}; bool judge(int x,int y) {
if(x <= || x > n || y <= || y > m || s[x][y] == '#') return false;
return true;
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
scanf("%d%d%d",&n,&m,&p);
for(int i = ; i <= p; i++) scanf("%d",&a[i]);
for(int i = ; i <= n; i++) {
scanf("%s",s[i] + );
for(int j = ; j <= m; j++) vis[i][j] = -;
}
queue<pii>q;
for(int k = ; k <= p; k++) {
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
if(s[i][j] - '' == k) {
q.push(mp(i,j));
vis[i][j] = k;
}
}
}
}
while(!q.empty()) {
pii now = q.front();
q.pop();
int x = now.first, y = now.second;
queue<node>q1;
q1.push({x,y,a[vis[x][y]]});
while(!q.empty() && vis[q.front().first][q.front().second] == vis[x][y]) {
q1.push({q.front().first,q.front().second,a[vis[x][y]]});
q.pop();
}
while(!q1.empty()) {
node hh = q1.front();
q1.pop();
if(hh.d <= ) continue;
for(int i = ; i < ; i++) {
int nx = hh.x + dx[i], ny = hh.y + dy[i], d = hh.d;
if(judge(nx,ny) && vis[nx][ny] == -) {
vis[nx][ny] = vis[x][y];
q1.push({nx,ny,d - });
q.push(mp(nx,ny));
}
}
}
}
int ans[] = {};
for(int i = ; i <= n; i++) {
for(int j = ; j <= m; j++) {
if(vis[i][j] != -) ans[vis[i][j]]++;
}
}
for(int i = ; i <= p; i++) printf("%d ",ans[i]);
return ;
}