CodeForces 1105D-暴力DFS

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;
} 

猜你喜欢

转载自www.cnblogs.com/tombraider-shadow/p/11220427.html