uva1103 Ancient Messages

来源:互联网 发布:淘宝自己的评价不见了 编辑:程序博客网 时间:2024/05/22 17:16


这题剥去洋洋洒洒的体面,就是求连通块个数,和连通块里空白区域的个数,最后判断是哪个象形字。

题意:给你象形字的图形,给你一个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");   }}


0 0