题目有一个 n*m 的棋盘, # 为墙, . 为空地 1 2 3 4.等为旗手的棋子,每个旗手有一个速度, 代表每回合能扩张几步,扩张方向包括上下左右,现在从 1 - p 开始依次扩张直到 棋盘满了, 求每个旗手最多走了多少个地板。。
需要 p 个队列储存 bfs 信息,同时需要记录步数和回合数, 每个回合只能扩张 v 次, 而如果全部棋盘都走满了则游戏结束。
以下为 AC 代码‘’
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct node
{
int x,y,st;
node(int x,int y,int st):x(x),y(y),st(st){}
};
queue<node>q[10];
int dx[4]={0,0,-1,1};
int dy[4]={1,-1,0,0};
bool vis[1005][1005];
char mp[1005][1005];
int n,m,p,v[10],siz[10];
inline bool check(int x,int y)
{
if(!vis[x][y]&&x<=n&&x>=1&&y<=m&&y>=1)
return true;
else
return false;
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
memset(vis, false ,sizeof vis);
for(int i=1;i<=p;i++)scanf("%d",&v[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>mp[i][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(mp[i][j]!='.')vis[i][j]=true;
if(mp[i][j] != '.'&&mp[i][j] != '#')
q[mp[i][j]-'0'].push(node(i, j, 0));
}
}
for(int i=1;i<=p;i++)siz[i]=q[i].size();
int turn=0;
while(true)
{
turn ++;
bool fl = false;
for(int i=1;i<=p;i++)
{
while(q[i].size())
{
node te=q[i].front();
if(te.st>=turn*v[i])break;
q[i].pop();
for(int k=0;k<4;k++)
{
node tk = node(te.x+dx[k], te.y+dy[k], te.st+1);
if(check(tk.x, tk.y))
{
vis[tk.x][tk.y] = true;
siz[i]++;
q[i].push(tk);
}
}
}
if(q[i].size()) fl=true;
}
if(!fl)break;
}
for(int i=1;i<=p;i++)
printf("%d%c",siz[i],i==p?'\n':' ');
return 0;
}