uva1103 Ancient Messages


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

题意:给你象形字的图形,给你一个01矩阵,拓扑等价画出这些象形字,判断图中 有哪些象形字。

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

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

详见代码。

#include <fstream>
#include <iostream>
#include <string>
#include <cstring>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>
#include <ctime>
#include <assert.h>

#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define eps 1e-8
#define M_PI 3.141592653589793

typedef long long ll;
const ll mod=1000000007;
const int inf=0x7fffffff;
ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
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&&y>=0&&x<=n+1&&y<=m+1);
}

void dfs(int x,int y)
{
    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(!in_M(x,y)||M[x][y]==-1) 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)){
        getchar();
        if(n==0&&m==0) return 0;
        //cout<<n<<m<<endl;
        memset(num,0,sizeof(num));
        memset(M,0,sizeof(M));
        for(int i=1;i<=n;i++){
            int len=1;
            for(int j=1;j<=m;j++){
                char c;scanf("%c",&c);
                for(int k=0;k<16;k++){
                    if(str[k]==c){
                        for(int l=0;l<4;l++){
                           M[i][len++]=s[k][l];
                        }
                        break;
                    }
                }
            }
            getchar();
        }
        m*=4;
        dfs(0,0);
        /*
        cout<<n<<m<<endl;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                cout<<M[i][j];
            }
            cout<<endl;
        }
        cout<<"ok"<<endl;
        */
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
               if(M[i][j]==1){
                  cnt=0;
                  dfs2(i,j);
                 // cout<<cnt<<endl;
               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++){
            if(num[i]>0){
                for(int j=0;j<num[i];j++){
                    printf("%c",res[i]);
                }
            }
        }
        printf("\n");
    }
}


你可能感兴趣的:(uva1103 Ancient Messages)