hdu 6113 度度熊的01世界/2017 百度之星

Problem Description
度度熊是一个喜欢计算机的孩子,在计算机的世界中,所有事物实际上都只由0和1组成。

现在给你一个n*m的图像,你需要分辨他究竟是0,还是1,或者两者均不是。

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

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

连通的含义是,只要连续两个方块有公共边,就看做是连通。

完全包围的意思是,该连通块不与边界相接触。

Input
本题包含若干组测试数据。 每组测试数据包含: 第一行两个整数n,m表示图像的长与宽。 接下来n行m列将会是只有01组成的字符画。

满足1<=n,m<=100

Output

如果这个图是1的话,输出1;如果是0的话,输出0,都不是输出-1。


分析:因为只有0,1而且1只能是一个联通快所以,对与0来说 如果只与1相邻 则说明0被1包围,如果0还达到了边界 则不被1包围。同理1也是。

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#define siz 105
using namespace std;
const int maxn = 100;
typedef long long LL;
int n,m;
char S[maxn+5][maxn+5];
int cnt,vis[maxn+5][maxn+5];// cnt 联通快的个数
int yes[maxn*maxn+5],is[maxn*maxn+5],hv[maxn*maxn+5][5];// yes 是否与达到边界, is表示联通快是1还是0, hv与那些相邻。
int f[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
void dfs(int x,int y)
{
    vis[x][y] = 1;
    for(int i=0; i<4; i++)
    {
        int nx = x+f[i][0] ,ny=y+f[i][1];
        if(nx<1||ny<1||nx>n||ny>m) continue;
        if(S[nx][ny]!=S[x][y])
        {
            hv[cnt][S[nx][ny]-'0'] = 1;// 第cnt个联通快与 S[nx][ny]相邻。
            continue;
        }
        if(vis[nx][ny]) continue;
        if(nx==1||nx==n||ny==1||ny==m) yes[cnt] = 1;//第cnt个联通快是否到底边界。
        dfs(nx,ny);
    }
}
int ok()
{
    int cot = 0,tot=0;
    cnt = 0;
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++) if(!vis[i][j])
            {
                cnt++;
                if(S[i][j]=='1') cot++;
                is[cnt] = S[i][j]-'0';
                if(i==1||i==n||j==1||j==m) yes[cnt] = 1;//注意 传进去的x,y点要 判断。
                dfs(i,j);
            }
    }
    if(cot!=1) return -1;//1联通快不是一个就为-1
    for(int i=1; i<=cnt; i++)
    {
        if(is[i]==0)
        {
            if(!yes[i]&&hv[i][1]) tot++;
        }
    }
    if(tot==1) return 0;// 被1包围的0的联通快为一个就为 0
    if(tot==0) return 1;// 不存在任何0字符组成的连通块被1所完全包围
    return -1;
}
int main()
{
    while(~scanf("%d %d",&n,&m))
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%s",S[i]+1);
        }
        for(int i=1; i<=n*m; i++) yes[i] = 0;
        memset(hv,0,sizeof(hv));
        memset(vis,0,sizeof(vis));
        int ty = ok();
        printf("%d\n",ty);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值