• UVA 1103 Ancient Messages


    题意:给定一个图像,字典序输出里面对应的象形文字。

    分析:把由十六进制构成的图转换成二进制的图,就能很容易理解题意。

    1、在最外圈加一圈0,便于使所有象形文字外的0都是连通的

    2、将所有连通的0和1都标号(dfs)

    3、再查象形文字里的洞的个数,把所有1附近的不是外圈的0都set一下就好了。

    #pragma comment(linker, "/STACK:102400000, 102400000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define Min(a, b) ((a < b) ? a : b)
    #define Max(a, b) ((a < b) ? b : a)
    typedef long long ll;
    typedef unsigned long long llu;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
    const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const double eps = 1e-8;
    const int MAXN = 200 + 10;
    const int MAXT = 50 + 10;
    using namespace std;
    char pic[MAXN][MAXT << 2];
    int vis[MAXN][MAXT << 2];
    char s[MAXN];
    map<char, string> mp;
    map<int, char> ma;
    set<int> in[44100];//连通块1里的洞的个数,set去重
    vector<int> y;//由1组成的连通块的标号
    vector<char> ans;
    int cnt, H, W;;
    void init(){//十六进制与二进制映射
        string a = "0123456789abcdef";
        string b = "0000000100100011010001010110011110001001101010111100110111101111";
        int len = a.size();
        int st = 0;
        for(int i = 0; i < len; ++i){
            mp[a[i]] = b.substr(st, 4);//从st开始取4个
            st += 4;
        }
        string tmp = "WAKJSD";
        for(int i = 0; i < 6; ++i){
            ma[i] = tmp[i];
        }
    }
    bool judge(int x, int y){
        return x >= 0 && x <= H + 1 && y >= 0 && y <= 4 * W + 1;
    }
    void dfs(int x, int y){
        vis[x][y] = cnt;
        for(int i = 0; i < 4; ++i){//题意中other black pixel on its top, bottom, left, or right side
            int tmpx = x + dr[i];
            int tmpy = y + dc[i];
            if(judge(tmpx, tmpy) && !vis[tmpx][tmpy] && pic[tmpx][tmpy] == pic[x][y]){
                dfs(tmpx, tmpy);
            }
        }
    }
    int main(){
        init();
        int cases = 0;
        while(scanf("%d%d", &H, &W) == 2){
            if(!H && !W) return 0;
            memset(pic, '0', sizeof pic);
            memset(vis, 0, sizeof vis);
            for(int i = 0; i < 44100; ++i){
                in[i].clear();
            }
            y.clear();
            ans.clear();
            for(int i = 1; i <= H; ++i){
                scanf("%s", s);
                string ans = "";
                for(int j = 0; j < W; ++j){
                    ans += mp[s[j]];
                }
                for(int j = 1; j <= 4 * W; ++j){
                    pic[i][j] = ans[j - 1];
                }
            }
            cnt = 0;//为每一个连通块标号
            for(int i = 0; i < H + 2; ++i){
                for(int j = 0; j < 4 * W + 2; ++j){
                    if(!vis[i][j]){
                        ++cnt;
                        dfs(i, j);
                        if(pic[i][j] == '1') y.push_back(cnt);
                    }
                }
            }
            for(int i = 0; i < H + 2; ++i){
                for(int j = 0; j < 4 * W + 2; ++j){
                    if(pic[i][j] == '1'){
                        for(int k = 0; k < 4; ++k){
                            int tmpx = i + dr[k];
                            int tmpy = j + dc[k];
                            if(judge(tmpx, tmpy) && pic[tmpx][tmpy] == '0' && vis[tmpx][tmpy] != 1){//象形文字里的0
                                in[vis[i][j]].insert(vis[tmpx][tmpy]);
                            }
                        }
                    }
                }
            }
            int len = y.size();
            for(int i = 0; i < len; ++i){
                ans.push_back(ma[in[y[i]].size()]);
            }
            sort(ans.begin(), ans.end());
            len = ans.size();
            printf("Case %d: ", ++cases);
            for(int i = 0; i < len; ++i){
                printf("%c", ans[i]);
            }
            printf("\n");
        }
        return 0;
    }

     一组完整的测试样例:

    100 25
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    00000f8000000000000000000
    00001fe000000000000000000
    00007ff000000000000000000
    00007ff800000000000000000
    0000f8f800000000000000000
    0001f07c00000000000000000
    0001e03c00000000001800000
    0001e01c00000000003c00000
    0001c01c00000000007c00000
    0003c01e0000000000f800000
    0003c01e0000000001f000000
    0001c01c0000000003f000000
    0001c01c0000000007e000000
    0001e01c000000000fc000000
    0001e03c000000001fc000000
    0000e03c000000001fc000000
    0000f038000000003ff000000
    0000f078000000003ff800000
    00007870000000007ff800000
    000038f0000000007cfc00000
    00003ce0000000007c7c00000
    00781fc0f0000000f87c00000
    007ffffff0000000f07c00000
    007ffffff0000000f07c00000
    007ffffff0000001f07c00000
    007ffffff0000000e03e00000
    007fcf81f0000000603e00000
    00000f8000000000003e00000
    00000f8000000000003e00000
    00000f8000000000003e00000
    00000f8000000000001e00000
    00000f8000000000001f00000
    00000fc000000000001f00000
    00000fc000000000001f00000
    00000fc000000000001f00000
    00000fc000000000000f00000
    00001fc000000000000f80000
    00001fc000000000000f80000
    00001fc000000000000f80000
    00001fc000000000000f80000
    00001fe000000000000f80000
    00001fe000000000000780000
    00001fe0000000000007c0000
    00001fe0000000000007c0000
    00003fe0000000000007c0000
    00003fe0000000000007c0000
    00003fe0000000000007c0000
    00003fe0000c00000003c0000
    00000000003ff0000003c0000
    00000000007ff8000003e0000
    0000000001fffc000003e0000
    0000000003e03f000003e0000
    0000000007c00f000003e0000
    000000000f0003800003f0000
    000000000e0001c00003fc000
    000000001c0001e00007fe000
    000000003c0000e0000fff000
    000000073c000070000fdf000
    0000001ff8000070001f0f800
    0000001ff8000070001e07800
    0000003cf0000078001e03800
    0000003870000033001e03800
    000000307800003fc01e03800
    000000703800007fe00e03800
    000000703800007ce00e03800
    000000703c000078700703800
    000000701e0000f0700701000
    000000701e0000e0700300000
    000000700f0001c0700000000
    0000006007800380600000000
    000000e003e00700600000000
    000000e001fe7e00600000000
    000000e000fffc00e00000000
    000000e0000ff000e00000000
    000000f800038000e00000000
    000000fff0000000e00000000
    000000fffff00000e00000000
    00000003ffffe000c00000000
    0000000007ffffc0c00000000
    000000000007ffffc00000000
    0000000000000fffc00000000
    000000000000001fc00000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000
    0000000000000000000000000

    输出:AKW

  • 相关阅读:
    函数waitpid和WTERMSIG说明(转)
    WIFEXITED WEXITSTATUS WIFSIGNALED(转)
    有关于malloc申请内存和free内存释放
    Using 1-Wire device with Intel Galileo
    Intel Galileo驱动单总线设备(DHT11DHT22)(转)
    360度舵机和180度舵机控制方法小结(转)
    warning: the `gets' function is dangerous and should not be used.(转)
    C语言fgetpos()函数:获得当前文件的读写指针(转)
    关于arduino清空串口缓存(转)
    修改Arduino串口缓冲区大小(转)
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/6272593.html
Copyright © 2020-2023  润新知