Description:
给出一个n*m棋盘,然后有p个玩家,每个玩家初始时占据棋盘中一格,游戏一轮轮进行,每一轮从1号玩家到p号玩家,轮流尽可能多的用自己已经占据的领地向四周以速度si进行扩展,问最后每个玩家都能占领多少格。
Input:
n,m,p,si(for i=1,2,...,p)
Output:
p个整数,分别代表每个玩家所占领的格子数。
Analysis:
已经扩散过的格子无需再进行扩散,可以用BFS进行扩展,每一个玩家的扩展用不同的队列一轮一轮模拟,同时标记距离来判断是否扩散完毕,并且统计答案。
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<unordered_set>
#include<ctime>
#include<cstring>
#include<assert.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1 << 30;
const int maxn = 1005;
const double eps = 1e-6;
int n, m, p;
vector<int> speed;
string pic[maxn];
int d[maxn][maxn], ans[10];
int dr[] = { 0,0,-1,1 }, dc[] = { -1,1,0,0 };
bool check(int r, int c) {
return r >= 0 && r < n&&c >= 0 && c < m&&d[r][c] == -1&&pic[r][c]!='#';
}
int main()
{
while (cin >> n >> m >> p) {
speed.resize(p);
for (auto &it : speed)
cin >> it;
for (int i = 0; i < n; ++i) {
cin >> pic[i];
}
vector<queue<pair<int, int> > > Q;
memset(d, -1, sizeof(d));
memset(ans, 0, sizeof(ans));
Q.resize(p);
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j) {
if (isdigit(pic[i][j])) {
Q[pic[i][j] - '0'-1].push({ i,j });
d[i][j] = 0;
ans[pic[i][j] - '0'-1]++;
}
}
for (int turn = 1;; turn++) {
bool finish =true ;
for (int i = 0; i < p; ++i) {
while (Q[i].size()) {
int rr = Q[i].front().first;
int cc = Q[i].front().second;
if (d[rr][cc] >= turn * speed[i]) break;
for (int dir = 0; dir < 4; ++dir) {
int nr = rr + dr[dir];
int nc = cc + dc[dir];
if (check(nr, nc)) {
d[nr][nc] = d[rr][cc] + 1;
Q[i].push({ nr,nc });
ans[i]++;
}
}
Q[i].pop();
}
if (Q[i].size()) {
finish = false;
}
}
if (finish)
break;
}
for (int i = 0; i < p; ++i)
cout << ans[i] << " ";
cout << endl;
}
return 0;
}