您的位置:首页 > 其它

uva1103 Ancient Messages

2016-01-16 13:44 176 查看
这题剥去洋洋洒洒的体面,就是求连通块个数,和连通块里空白区域的个数,最后判断是哪个象形字。

题意:给你象形字的图形,给你一个01矩阵(16进制一位等于四位2进制),拓扑等价画出这些象形字,判断图中 有哪些象形字。

思路:观察可以发现,每个象形字的空白块数是不同的,因此用dfs求出每个象形区域的联通块数就可以判断是那个字,按照字典序输出。

  最初,我在想怎么找到恰好每个字的范围才能找它里面有多少空白区域。所以这里有两个dfs,一个把字以外的区域-1化,一个在字里找空白个数。这题还有一点16进制转二进制简单字符串处理。

详见代码。

#include<bits/stdc++.h>
using namespace std;
char res[]={'A','D','J','K','S','W'};
char str[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
int s[16][4]=
{
    {0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1},
    {0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1},
    {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1},
    {1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}
};
int num[6];
int M[250][250],n,m,cnt;
bool in_M(int x,int y)
{
    return (x>=0&&x<=n+1&&y>=0&&y<=m+1);
}

void dfs(int x,int y)//将字外围空白部分-1化,缩小化字出现的地方
{
   if(!in_M(x,y)||M[x][y]!=0) return;
   M[x][y]=-1;
   dfs(x+1,y);dfs(x-1,y);dfs(x,y+1);dfs(x,y-1);
}

void dfs2(int x,int y)//找到一个字出现地方搜索内部的空白区域个数
{
    if(M[x][y]==-1||!in_M(x,y)) return;
    if(M[x][y]==0){
        cnt++;
        dfs(x,y);
        return;
    }
    M[x][y]=-1;
    dfs2(x+1,y);dfs2(x-1,y);dfs2(x,y+1);dfs2(x,y-1);
}

int main()
{
   int t=0;
   while(scanf("%d %d",&n,&m)&&n&&m){
      memset(M,0,sizeof(M));
      for(int i=1;i<=n;i++){
        char tem[80]; scanf("%s",tem+1);
        int p=1;
        for(int j=1;j<=m;j++){
           for(int k=0;k<16;k++){
             if(tem[j]==str[k]){
                for(int l=0;l<4;l++){
                   M[i][p++]=s[k][l];
                }
                break;
             }
           }
        }
      }
      memset(num,0,sizeof(num));
      m*=4;
      dfs(0,0);
      for(int i=0;i<=n;i++){
        for(int j=0;j<=m;j++){
            if(M[i][j]==1){
                cnt=0;
                dfs2(i,j);
                if(cnt==0) num[5]++;
                else if(cnt==1) num[0]++;
                else if(cnt==2) num[3]++;
                else if(cnt==3) num[2]++;
                else if(cnt==4) num[4]++;
                else if(cnt==5) num[1]++;
             }
        }
      }
     printf("Case %d: ",++t);
     for(int i=0;i<6;i++){
        for(int j=0;j<num[i];j++){
            printf("%c",res[i]);
        }
    }
    printf("\n");
   }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: