CF1345D Monopole Magnets(构造)

对于存在不可能情况的构造题,我们的思路一般都是找到不存在的情况后,再进行构造。

这题首先能看出来的是,不能存在两个黑色之间有白色,因为这样一定会有一个黑色被吸引

在上面的情况下,如果存在某一列或某一行都是白的,但是没有与之对应的空白行列,那么也是非法的

满足了上面的情况下。答案就是连通块的数量,因为我们可以贪心的在每个黑色上面都放s,这样只需要一个n就能遍历一个连通块

如果所有行列都存在黑色且满足最上面的条件,那么白的摆放要求也能够满足。

不然如果存在某一行是白的,那么必定存在某一列也是白的,这点也可以想到。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2e5+10;
char s[1200][1200];
int st[1200][1200];
int n,m;
void dfs(int x,int y){
    if(s[x][y]=='.')
        return ;
    int dx[]={-1,0,1,0};
    int dy[]={0,1,0,-1};
    for(int i=0;i<4;i++){
        int l=x+dx[i],r=y+dy[i];
        if(l>=1&&l<=n&&r>=1&&r<=m){
            if(s[l][r]=='#'&&!st[l][r]){
                st[l][r]=1;
                dfs(l,r);
            }

        }
    }
}
int main(){
    cin>>n>>m;
    int i,j;
    for(i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    int cnt=0;
    int flag=0;
    int row=0;
    for(i=1;i<=n;i++){
        cnt=0;
        for(j=1;j<=m;j++){
            if(s[i][j]=='#'&&(s[i][j-1]!='#'||j==1))
                cnt++;
            if(cnt>=2){
               flag=1;
               break;
            }
        }
        if(!cnt)
            row=1;
    }
    int col=0;
    for(j=1;j<=m;j++){
        cnt=0;
        for(i=1;i<=n;i++){
            if(s[i][j]=='#'&&(s[i-1][j]!='#'||i==1))
                cnt++;
            if(cnt>=2){
                flag=1;
                break;
            }
        }
        if(!cnt)
            col=1;
    }
    if(flag){
        cout<<"-1"<<endl;
        return 0;
    }
    else if(row^col){
        cout<<"-1"<<endl;
        return 0;
    }
    cnt=0;
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            if(s[i][j]=='.')
                continue;
            if(!st[i][j]){
                dfs(i,j);
                cnt++;
            }
        }
    }
    cout<<cnt<<endl;
}
View Code

 

posted @ 2020-05-24 21:56  朝暮不思  阅读(208)  评论(0编辑  收藏  举报