UVA - 1103 Ancient Messages

题目大意: 给你几个符号,然后用点来表示那个位置有没有被涂黑,每个点是16进制,所以先得把它转换成2进制,判断符号类型,然后按字典序输出。

思路:讲道理这个脑洞我是开不出来的,还是按紫书的思路写的,因为每个字符的内部的空白块的个数不一样,具体做法是把符号外部的空白格子标记,然后把每个符号标记,在标记符号的同时,找周围有没有空白的格子,如果有,肯定是符号内部的空白格,因为此时外部的空白格已经全部被标记过了。按这样找完整张图。 标记外部的空白格记得把图开大一圈,这样就可以标记外部的0了。


代码:

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int a[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}};

char dy[6] = {'W','A','K','J','S','D'};
int ta[810][410];
int way[4][2] = {0,1,0,-1,1,0,-1,0};
int m,n;
char ans[1005];
int check(int i,int j)
{
    if(i >= 0 && i <= m+1 && j >= 0 && j <= 4*n+1) return 1;
    else return 0;
}

int dfsw(int a,int b,int mark)      //标记空白用
{
    ta[a][b] = mark;
   // cout<<"a b "<
    for(int i = 0; i < 4 ; i++)
    {
        int ca = a +way[i][0], cb = b + way[i][1];
            if(check(ca,cb) && ta[ca][cb] == 0)
            dfsw(ca,cb,mark);
    }
}
int epnum = 0;
int dfsf(int a,int b,int mark)      //标记符号
{
    ta[a][b] = mark;
    for(int i = 0; i < 4 ; i++)
    {
        int ca = a +way[i][0], cb = b + way[i][1];
        if(check(ca,cb) && ta[ca][cb] == 1)
            dfsf(ca,cb,mark);
        else if(check(ca,cb) && ta[ca][cb] == 0)    //一旦在附近找到空格,就标记这个空格,内部空格数+1
        {                                           //因为外部的空格已经被标记为-1,所以是不会找到外部的空格的。
            epnum++;
            dfsw(ca,cb,mark);
        }
    }
}
int num = 1;
int main()
{
    //freopen("D://in.txt","r",stdin);
    int kase = 1;
    while(~scanf("%d%d",&m,&n) && m+n)
    {
        memset(ta,0,sizeof(ta));
        for(int i = 0; i < m ; i++)
        {
            char s[210];
            scanf("%s",s);
            for(int j = 0; j < n ; j++)
            {
                if(islower(s[j]) )
                {
                    int x = 4*j;
                    for(int k = 4*j+1; k < 4*j+5; k++)
                        ta[i+1][k] = a[s[j]-'a'+10][k-x-1];
                }
                else
                {
                    int x = 4*j;
                    for(int k = x+1; k < x+5; k++)
                        ta[i+1][k] = a[s[j]-'0'][k-x-1];
                }
            }
        }
        ta[0][0] = -1;
        dfsw(0,0,-1);       //标记外部的空白格
        num = 2;
        int anum = 0;
        for(int i = 0; i <= m; i++)
        {
            for(int j = 0; j < 4*n+1; j++)
            {
                if(ta[i][j] == 1)       //找到一个符号
                {
                    epnum = 0;
                    ta[i][j] = num;
                    dfsf(i,j,num);      //把这个符号特别的标记一下 以免又找一遍
                    num++;
                    ans[anum++] = dy[epnum];    
                }
            }
        }
        sort(ans,ans+anum);
        printf("Case %d: ",kase++);
        for(int i = 0; i < anum; i++)
            cout<cout<return 0;
}

你可能感兴趣的:(紫书)