Codeforces 1105D

很好的搜索题,多个对象,每个对象可以一次走多步。问最后每个对象占了多少个格子。
每个对象一个队列,对于一个对象走不只一步的问题,先记录当前队列元素的个数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;
} 

猜你喜欢

转载自blog.csdn.net/winhcc/article/details/88746008