zoukankan      html  css  js  c++  java
  • CF1105D-Kilani and the Game-(多向bfs)

    http://codeforces.com/problemset/problem/1105/D

    题意:有一片矩阵区域,一开始有多个势力比如1,2,3,4....9,从势力1开始轮流向外扩张,地图上为‘.’可以占领,‘#’则不能占领,被占领后不能再次被别人占领,只能上下左右扩张,每个势力有一个扩张速度,求最后整片区域上各个势力占了多少格子。

    解题:

    1.显然bfs,但是速度有大有小,多向bfs

    2.输入的数据同一势力的起点可能不止一个(坑)

    3.从势力1开始轮流扩张,不是队列一次走到头

    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #include<map>
    #include<queue>
    #include<stack>
    #include<set>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    
    int n,m,p;
    int last[10];///上一次压入了多少个点
    struct node
    {
        int x;
        int y;
    };
    int s[10];///速度
    char a[1005][1005];
    int vis[1005][1005];
    int ans[10];
    int can[10];///是否走投无路
    queue<node>que[10];
    int d[4][2]={ {-1,0}, {1,0}, {0,-1}, {0,1} };///上下左右
    
    void bfs()
    {
        for(int i=1;i<=p;i++)///清空
        {
            while(!que[i].empty())
                que[i].pop();
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if( a[i][j]!='.' && a[i][j]!='#' )
                {
                    que[ a[i][j]-'0' ].push( {i,j} );///压入起点,可能不止一个
                    vis[i][j]=a[i][j]-'0';
                    last[ a[i][j]-'0' ]++;
    
                }
            }
        }
        bool flag=true;
        while(flag)///有人还能延伸就继续
        {
            flag=false;
            for(int idx=1;idx<=p;idx++)///每个队列走一次
            {
                for(int ss=1;ss<=s[idx] && can[idx]==0 ;ss++)///扩展速度,能走多少步,s[i]可能很大超时,用can数组截断
                {
                    int num=last[idx];///本次允许弹出去扩张的节点的数量,即上次压入的节点数量
                    last[idx]=0;///新一轮扩张加入的节点要清空
                    for(int t=1;t<=num;t++)
                    {
                        node now=que[idx].front();
                        que[idx].pop();
                        ans[idx]++;///取队头,弹出的时候区域+1
                        for(int i=0;i<4;i++)
                        {
                            int xx=now.x+d[i][0];
                            int yy=now.y+d[i][1];
                            if( xx>=0 && xx<n && yy>=0 && yy<m && vis[xx][yy]==0 && a[xx][yy]=='.' )
                            {
                                que[idx].push( {xx,yy} );
                                vis[xx][yy]=idx;///压入队列,标记访问过
                                last[idx]++;///本次压入点的个数
                            }
                        }
    
                    }
                    if(que[idx].empty())
                        can[idx]=idx;///走投无路,美德扩展了
                }
            }
            for(int i=1;i<=p;i++)
            {
                if(!que[i].empty())
                    flag=true;
            }
        }
        for(int i=1;i<=p;i++)
            printf("%d ",ans[i]);
        printf("
    ");
    }
    
    int main()///CF1105D
    {
        while(scanf("%d %d %d",&n,&m,&p)!=EOF)
        {
            memset(a,0,sizeof(a));
            memset(s,0,sizeof(s));
            memset(ans,0,sizeof(ans));
            memset(vis,0,sizeof(vis));
            memset(last,0,sizeof(last));
            memset(can,0,sizeof(can));
            for(int i=1;i<=p;i++)///速度
                scanf("%d",&s[i]);
            getchar();
            for(int i=0;i<n;i++)///地图
                scanf("%s",a[i]);
    
            bfs();
        }
        return 0;
    }
  • 相关阅读:
    并查集 [Total Eclipse]
    2020 Multi-University Training Contest 2 [The Oculus]
    2020牛客暑期多校训练营(第三场)G Operating on a Graph
    杭电多校第一场 [Fibonacci Sum]
    Codeforces Round #658 (Div. 2) E. Mastermind
    二次剩余
    SpringBlade 后端项目 部署 2.0-boot
    SpringBlade 前端项目 部署 Saber
    前端 天气插件
    SpringBlade 打包
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/11167509.html
Copyright © 2011-2022 走看看