HDU6113 2017百度之星 初赛A轮F

题目在这里>_<

题意

度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成。
现在给你一个$n*m$的图像,你需要分辨他究竟是$0$,还是$1$,或者两者均不是。

  • 图像$0$的定义:存在$1$字符且$1$字符只能是由一个连通块组成,存在且仅存在一个由$0$字符组成的连通块完全被$1$所包围。
  • 图像$1$的定义:存在$1$字符且$1$字符只能是由一个连通块组成,不存在任何$0$字符组成的连通块被$1$所完全包围。

连通的含义是,只要连续两个方块有公共边,就看做是连通。
完全包围的意思是,该连通块不与边界相接触。

思路

维护并查集。
对于$0$,如果在边界上,则与$0$合并,否则正常合并。
对于$1$,按正常并查集进行操作即可。
最后只需check一下是否满足条件。
写得太丑了。。。

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
#include <set>
//#define test
using namespace std;
const int Nmax=1e3+7;
typedef long long ll;
int dx[]={0,0,0,1,-1};
int dy[]={0,1,-1,0,0};
int n,m;
int mp[Nmax][Nmax];
int id(int x,int y)
{
    return (x-1)*m+y;
}
int fa[Nmax*Nmax];
int find(int x)
{
    if(fa[x]!=x)
        fa[x]=find(fa[x]);
    return fa[x];
}
void merge(int a,int b)
{
    int r1=find(a),r2=find(b);
    if(r1!=r2)
        fa[r1]=r2;
}
void init()
{
    for(int i=0;i<=n*m+10;i++)
        fa[i]=i;
}
vector<int> check[3];
int es(int x,int cc)
{
    for(int i=0;i<(int)check[cc].size();i++)
    {
        if(x==check[cc][i])
            return 1;
    }
    return 0;
}
int is1()
{
    int r0=find(0);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j])
                continue;
            int now=find(id(i,j));
            if(now!=r0)
                return 0;
        }
    }
    return 1;
}
int check_one()
{
    check[1].clear();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(!mp[i][j])
                continue;
            int now=find(id(i,j));
            if(es(now,mp[i][j])) 
                continue;
            else
                check[1].push_back(now);
            if(check[1].size()>=2)
                return 0;
        }
    }
    if(check[1].size()!=1)
        return 0;
    return 1;
}
int is0()
{
    int r0=find(0);
    int ct0=0;
    check[0].clear();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(mp[i][j])
                continue;
            int now=find(id(i,j));
            if(es(now,0)) 
                continue;
            else
                check[0].push_back(now);
            if(check[0].size()>=3)
                return 0;
        }
    }
    if(check[0].size()>=3)
        return 0;
    for(int i=0;i<(int)check[0].size();i++)
    {
        if(check[0][i]!=r0) 
            ct0++;
    }
    if(ct0!=1)
        return 0;
    return 1;
}
int main()
{
    #ifdef test
    #endif
    char c;
    //freopen("6.in","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        getchar();
        //printf("%d %d\n",n,m);
        init();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                c=getchar();
                mp[i][j]=c-'0';
            }
            getchar();

        }
        //for(int i=1;i<=n;i++)
            //for(int j=1;j<=m;j++)
                //printf("%d%c",mp[i][j],j==m?'\n':' ');
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                for(int k=1;k<=4;k++)
                {
                    int nowx=i+dx[k],nowy=j+dy[k];
                    if(!mp[i][j])
                    {
                        if(nowx<1 || nowy<1 || nowx>n || nowy>m)
                            merge(id(i,j),0);
                        else
                        {
                            if(!mp[nowx][nowy])
                            {
                                merge(id(i,j),id(nowx,nowy));
                            }
                        }
                    }
                    else
                    {
                        if(nowx<1 || nowy<1 || nowx>n || nowy>m)
                            continue;
                            //merge(id(i,j),n*m+3);
                        else
                        {
                            if(mp[nowx][nowy])
                            {
                                merge(id(i,j),id(nowx,nowy));
                            }
                        }
                    }
                }
            }
        }
        if(!check_one())
            printf("-1\n");
        else if(is0())
            printf("0\n");
        else if(is1())
            printf("1\n");
        else
            printf("-1\n");
    }
    return 0;
}