CodeForces 1105D Kilani and the Game
题目链接:Kilani and the Game
题目大意:给你一个n*m的地图,这个地图上有p个国家,每个国家都有自己的城堡,在地图上以数字显示,每个国家都会向外扩张
,但是在每次扩张中最多扩张s[i]个单位,回合轮流进行,问最后每个国家城堡的数量
题目思路:想到每个城堡都有向外扩张的可能,所以可以使用bfs来对每个城堡进行扩张,但是每个城堡又有扩张上线,所以我们用一个结构体
来保存x,y,step,step表示还能扩张几次,同时每个回合的每个国家都是从边缘地带扩张,so需要bode[who]来保存在边缘上的位置,然后进行bfs就
可以了
/*此代码在Dev5.11上会有警告*/ #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1000+5; int n,m,p,vis[maxn][maxn],ans[maxn],s[maxn]; char a[maxn][maxn]; struct node { int x,y,step; }; queue<node>boder[10],q; int dir[4][2]={1,0,-1,0,0,1,0,-1}; void bfs(int who) { node tmp; int x,y; while(!q.empty()) { tmp=q.front(); q.pop(); if(tmp.step==0) boder[who].push(tmp); else { for(int i=0;i<4;i++) { x=tmp.x+dir[i][0]; y=tmp.y+dir[i][1]; if(x<1||y<1||x>n||y>m||a[x][y]!='.'||vis[x][y]!=0) continue; vis[x][y]=who; q.push(node{x,y,tmp.step-1}); //入队表示这里已经扩张,step需要-1; } } } return ; } bool expand(int who) { node tmp; while(!boder[who].empty()) { tmp=boder[who].front(); //每个国家的边缘如普通队列来扩张 boder[who].pop(); tmp.step=s[who]; q.push(tmp); } bfs(who); return !boder[who].empty(); } int main() { scanf("%d%d%d",&n,&m,&p); for(int i=1;i<=p;i++) scanf("%d",&s[i]); for(int i=1;i<=n;i++) scanf("%s",a[i]+1); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(a[i][j]>='0'&&a[i][j]<='0'+p) { int num=a[i][j]-'0'; boder[num].push(node{i,j,s[num]}); //先处理,将每个国家的boder入队 vis[i][j]=num; } } } while(1) { bool ok=false; for(int i=1;i<=p;i++) ok|=expand(i); //枚举每一个国家回合的扩张结果,如果在此回合有一个国家扩张,那么ok就为正,就有下一个回合 if(!ok) break; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans[vis[i][j]]++; for(int i=1;i<=p;i++) printf("%d ",ans[i]); return 0; }