zoukankan      html  css  js  c++  java
  • Codeforces 1344B/1345D


    半天看不懂题意只能补。。。


    题面

    Prob




    题意

    给定一张黑白图,要求放置南北磁极,南磁极不可移动(每行每列至少要有一个南磁极)

    每次可以激活一对在同行或同列的南北磁极,使得北磁极向南磁极移动一格

    要求在所有可能的移动过程中,北磁极不能到达白块,且又可以到达所有黑块

    问最少需要放置多少个北磁极,才能走遍图中所有黑块

    如果无法放置,输出 -1




    解题思路


    ①如果某行或者某列存在两段及以上黑色块组成的线段

    例如:

    PIC0

    因为每行或每列必定存在至少一个南磁极,所以肯定存在一个移动方式使得北磁极经过中间的那段白色块

    所以这种情况出现时不符题意,输出 -1

    由此可得,只有黑色块组成线段只存在一段时才符合题意

    所以例如: ..###.. | ###.... | ....### 都可行

    而样例 2 的第一列: #..# 不可行


    ②如果某列全空且没有行全空,或者某行全空且没有列全空

    例如:

    PIC1

    上图中第三列全空,但没有任何一行为空

    又因为每列必须有至少一个南磁极

    所以也一定存在一种移动方式能够让北磁极移动到这个全白的列上,不符题意


    ③如果存在某列全空,且存在某行全空

    例如:

    PIC2

    那么只要让南磁极放置在交叉点上,则不会影响分割出来的四个象限里的北磁极的移动

    即:

    PIC3

    如果存在多个交叉点,则在每个交叉点上都放置一个南磁极即可

    例如:

    PIC4


    综上我们可以得到:

    1. 每一行或者每一列至多存在一条由黑色块组成的线段
    2. 全白行与全白列,要么同时存在,要么同时不存在

    于是我们就把北磁极的移动路线固定在了每个黑色连通块之中

    最后通过bfs或者dfs求出连通块数量即可




    代码实现

    在判断黑色块线段数量时,引入变量kd,初始值为0

    循环某行或者某列

    如果碰到了 '#' 且 kd 是 0 则变成 1 ,是 2 则直接输出 -1 并结束程序

    如果碰到了 '.' 且 kd 是 1 则变成 2

    所以最后如果kd==0,说明整行全是白色块

    如果kd==1,说明这一行只有一段黑色块,且最后一个位置为黑色块

    如果kd==2,说明这一行只有一段黑色块,且最后一个位置为白色块

    否则就是直接输出 -1 的情况,说明由两段黑色块线段




    完整程序

    (46ms/2000ms)

    #include<bits/stdc++.h>
    using namespace std;
    typedef pair<int,int> P;
    
    char mp[1050][1050];
    int n,m,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
    
    inline bool prim(int x,int y)
    {
        return x>0&&y>0&&x<=n&&y<=m;
    }
    
    void bfs(int x,int y)
    {
        mp[x][y]='.';
        queue<P> q;
        q.push(P(x,y));
        while(!q.empty())
        {
            P pd=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                int px=pd.first+dx[i],py=pd.second+dy[i];
                if(prim(px,py)&&mp[px][py]=='#')
                {
                    mp[px][py]='.'; //把访问到的黑色块直接变成其他值即可
                    q.push(P(px,py));
                }
            }
        }
    }
    
    void solve()
    {
        cin>>n>>m;
        
        bool emptyRow=false,emptyColumn=false;
        
        for(int i=1;i<=n;i++)
        {
            cin>>(mp[i]+1);
            int kd=0;
            for(int j=1;j<=m;j++) //遍历行
            {
                if(mp[i][j]=='.')
                {
                    if(kd==1)
                        kd=2;
                }
                else
                {
                    if(kd==0)
                        kd=1;
                    else if(kd==2)
                    {
                        cout<<"-1
    ";
                        return;
                    }
                }
            }
            if(kd==0)
                emptyColumn=true; //说明这行全是白色块
        }
        
        for(int j=1;j<=m;j++)
        {
            int kd=0;
            for(int i=1;i<=n;i++)//遍历列
            {
                if(mp[i][j]=='.')
                {
                    if(kd==1)
                        kd=2;
                }
                else
                {
                    if(kd==0)
                        kd=1;
                    else if(kd==2)
                    {
                        cout<<"-1
    ";
                        return;
                    }
                }
            }
            if(kd==0)
                emptyRow=true; //说明这列全是白色块
        }
        
        if(emptyColumn!=emptyRow) //如果行全白且没有列全白,或者列全白且没有行全白
        {
            cout<<"-1
    ";
            return;
        }
        
        int ans=0;
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++) //遍历整张图
                if(mp[i][j]=='#') //如果存在没有访问到的黑色块
                {
                    bfs(i,j);
                    ans++;
                }
        
        cout<<ans<<'
    ';
    }
    int main()
    {
        ios::sync_with_stdio(0);
        cin.tie(0);cout.tie(0);
        solve();
        return 0;
    }
    

  • 相关阅读:
    【Language】 TIOBE Programming Community Index for February 2013
    【diary】good health, good code
    【web】a little bug of cnblog
    【Git】git bush 常用命令
    【web】Baidu zone ,let the world know you
    【diary】help others ,help yourself ,coding is happiness
    【Git】Chinese messy code in widows git log
    【windows】add some font into computer
    SqlServer启动参数配置
    关于sqlserver中xml数据的操作
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12843792.html
Copyright © 2011-2022 走看看