很好的搜索题,多个对象,每个对象可以一次走多步。问最后每个对象占了多少个格子。
每个对象一个队列,对于一个对象走不只一步的问题,先记录当前队列元素的个数m,一次只处理m个即可。
最后s可能到1e9,因此当队列中没有元素的时候就应该跳出循环,不然会T。
#include <bits/stdc++.h>
#define f first
#define s second
using namespace std;
typedef pair<int,int> PII;
const int N = 1010;
int n,m,t,flag,vis[N][N],s[10],res[10];
int dx[] = {-1,1,0,0},dy[]={0,0,-1,1};
char mp[N][N];
queue<PII> Q[10];
void bfs(int x){
for(int i = 0;i<s[x];i++){
int cnt = Q[x].size(),o = 0;
if(!cnt) break;
while(o++<cnt){
PII u = Q[x].front();Q[x].pop();
//cout<<u.f<<' '<<u.s<<endl;
for(int i = 0;i<4;i++){
int nx = u.f + dx[i],ny = u.s + dy[i];
if(nx>=0 && nx <n &&ny>= 0 &&ny < m
&& mp[nx][ny] != '#'
&& vis[nx][ny] == -1){
flag = 1;
vis[nx][ny] = x;
Q[x].push({nx,ny}) ;
}
}
}
}
}
int main(){
cin>>n>>m>>t;
for(int i = 1;i<=t;i++) cin>>s[i];
for(int i = 0;i<n;i++) cin>>mp[i];
memset(vis,-1,sizeof(vis));
for(int i = 0;i<n;i++)
for(int j = 0;j<m;j++)
if(mp[i][j] >= '1' && mp[i][j] <= '9') Q[mp[i][j]-'0'].push({i,j}),vis[i][j] = mp[i][j]-'0';
while(1){
flag = 0;
for(int i = 1;i<=t;i++) bfs(i);
if(!flag) break;
}
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
if(vis[i][j] != -1) res[vis[i][j]]++;
}
}
for(int i = 1;i<=t;i++)
cout<<res[i]<<' ';
return 0;
}