您的位置:首页 > 其它

HDU -- 6113 度度熊的01世界 【搜联通块 + 思维】

2017-08-13 12:42 387 查看
传送门

//题意就是题目中的意思.

//大概思路有两种. 第一种直接通过0,1联通快的数量来判定图像. 但是有个问题就是例如这种

3 3

010

111

010

那么如果根据一般的判定条件, 会输出-1, 而实际上是1, 所以我们需要做一点小小的改变. 就是在图的外侧加一圈0, 这样这个例子0,1联通快的数量就又都是1了, 这样就好判断了.

AC Code

/** @Cain*/
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
const int maxn=1e2+5;
int n,m;
char a[maxn][maxn];
bool vis[maxn][maxn];
void dfs(int x,int y,int flag)
{
for(int i=0;i<4;i++){
int xx = x+dx[i];
int yy = y+dy[i];
if(flag == 0 && (xx<0 || xx>n+1 || yy<0 || yy>m+1 || a[xx][yy] != '0')) continue;
if(flag == 1 && (xx<0 || xx>n+1 || yy<0 || yy>m+1 || a[xx][yy] != '1')) continue;
if(vis[xx][yy]) continue;
vis[xx][yy] = true;
dfs(xx,yy,flag);
}
}

void solve()
{
while(~scanf("%d%d",&n,&m)){
Fill(a,0);
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
for(int i=0;i<=m+1;i++) a[0][i] = a[n+1][i] = '0';
for(int i=0;i<=n+1;i++) a[i][0] = a[i][m+1] = '0';
Fill(vis,false);
int ans0= 0,ans1 = 0;
for(int i=0;i<=n+1;i++){
for(int j=0;j<=m+1;j++){
if(vis[i][j]) continue;
if(a[i][j] == '0'){
dfs(i,j,0);
vis[i][j] = true;
ans0++;
}
else{
dfs(i,j,1);
vis[i][j] = true;
ans1++;
}
}
}
if(ans0 == 1 && ans1 == 1) puts("1");   //对应输出判断条件就是了.
else if(ans0 == 2 && ans1 == 1) puts("0");
else puts("-1");
}
}


//第二种思路是, 题目的意思就是看1的联通快中有无0的联通快. 那么我们再搜0的联通快的时候, 加一个边界判定条件, 如果搜到了边界, 则就不算这个联通快. 即我们只算内部0的联通快有多少个. 然后判断一下就可以了.

AC Code

/** @Cain*/
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
const int maxn=1e2+5;
int n,m;
char a[maxn][maxn];
bool vis[maxn][maxn];
int flag;
bool check(int x,int y,char ch)
{
if(x<1 || x>n || y<1 || y>m || vis[x][y] || a[x][y] != ch) return false;
return true;
}

void dfs0(int x,int y)
{
vis[x][y] = true;
if(x==1 || x==n || y==1 || y==m) flag = true;//判定边界条件
for(int i=0;i<4;i++){
int xx = x+dx[i];
int yy = y+dy[i];
if(check(xx,yy,a[x][y]))
dfs0(xx,yy);
}
}

void dfs1(int x,int y)
{
vis[x][y] = true;
for(int i=0;i<4;i++){
int xx = x+dx[i];
int yy = y+dy[i];
if(check(xx,yy,a[x][y]))
dfs1(xx,yy);
}
}

void solve()
{
while(~scanf("%d%d",&n,&m)){
Fill(a,0); Fill(vis,false);
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
int ans0=0,ans1=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(vis[i][j]) continue;
if(a[i][j] == '0'){
flag = false;
dfs0(i,j);
if(!flag) ans0++; //只算内部0的联通快的数量.
}
if(a[i][j] == '1'){
dfs1(i,j);
ans1++;
}
}
}
if(ans1 == 1){
if(ans0 == 1) puts("0");
else if(ans0 == 0) puts("1");
else puts("-1");
}
else puts("-1");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: