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

  • 相关阅读:
    Ext.Net学习笔记12:Ext.Net GridPanel Filter用法
    Ext.Net学习笔记13:Ext.Net GridPanel Sorter用法
    Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法
    Ext.Net学习笔记11:Ext.Net GridPanel的用法
    Ext.Net学习笔记09:Ext.Net Store的用法
    Ext.Net学习笔记10:Ext.Net ComboBox用法
    Ext.Net学习笔记08:Ext.Net中使用数据
    Ext.Net学习笔记07:Ext.Net DirectMethods用法详解
    Ext.Net学习笔记06:Ext.Net DirectEvents用方补充
    Ext.Net学习笔记04:Ext.Net布局
  • 原文地址:https://www.cnblogs.com/stelayuri/p/12843792.html
Copyright © 2011-2022 走看看