• UVa 1103 (利用连通块来判断字符) Ancient Messages


    本题就是灵活运用DFS来求连通块来求解的。

    题意:

    给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符。然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号。

    分析:

    首先图像是被压缩过的,所以我们要把它解码成一个01矩阵。而且我们还要在原图像的四周加一圈白边,这样图中的白色背景都连通起来了。

    黑色连通块的个数就是字符的个数

    观察题中字符样式可知,每种字符中包裹的“白洞”的个数是不同的,所以我们可以根据每个字符中的“白洞”的个数来区别这些字符。

    然后我们给所有的连通块染色,并用color存储所标记的颜色。第一个染的是白色背景色,编号为1

    把所有的黑色连通块的标号存放到cc里面

    neighbors是由若干个集合所组成的数组,记录的是黑色连通块i周围相连的非背景色的白块,即“白洞”。

    最后每个集合中元素的个数对应的就是字符的编号,最后排序输出即可。

    一个DEBUG很久的低级错误:在DFS的时候忘了加 color[row2][col2] == 0 这一判断条件,相当于没有回溯了,当然会栈溢出,RE。这里的color顺带也起到了表示是否访问过的作用。

      1 //#define LOCAL
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <vector>
      6 #include <set>
      7 using namespace std;
      8 
      9 const int maxl = 200 + 5;
     10 char bin[256][5], s[maxl];
     11 const int dr[] = { 1, 0, -1, 0 };
     12 const int dc[] = { 0, 1, 0, -1 };
     13 int picture[maxl][maxl], color[maxl][maxl], w, h;
     14 
     15 vector<set<int> > neighbor;
     16 
     17 void decode(int row, int col, char c)
     18 {
     19     for(int i = 0; i < 4; ++i)
     20         picture[row][col + i] = bin[c][i] - '0';
     21 }
     22 
     23 bool inside(int row, int col)
     24 {
     25     return row>=0 && row<h && col>=0 && col<w;
     26 }
     27 
     28 void DFS(int row, int col, int c)
     29 {
     30     color[row][col] = c;
     31     for(int i = 0; i < 4; ++i)
     32     {
     33         int row2 = row + dr[i];
     34         int col2 = col + dc[i];
     35         if(inside(row2, col2) && picture[row][col] == picture[row2][col2] && color[row2][col2] == 0)
     36             DFS(row2, col2, c);
     37     }
     38 }
     39 
     40 void check_neighbor(int row, int col)
     41 {
     42     for(int i = 0; i < 4; ++i)
     43     {
     44         int row2 = row + dr[i];
     45         int col2 = col + dc[i];
     46         if(row2>=0 && row2<h && col2>=0 && col2<w && picture[row2][col2] == 0 && color[row2][col2] != 1)//寻找"洞"
     47             neighbor[color[row][col]].insert(color[row2][col2]);
     48     }
     49 }
     50 
     51 const char* code = "WAKJSD";
     52 
     53 char recgonize(int c)
     54 {
     55     int a = neighbor[c].size();
     56     return code[a];
     57 }
     58 
     59 int main(void)
     60 {
     61     #ifdef LOCAL
     62         freopen("1103in.txt", "r", stdin);
     63     #endif
     64 
     65     strcpy(bin['0'], "0000");
     66     strcpy(bin['1'], "0001");
     67     strcpy(bin['2'], "0010");
     68     strcpy(bin['3'], "0011");
     69     strcpy(bin['4'], "0100");
     70     strcpy(bin['5'], "0101");
     71     strcpy(bin['6'], "0110");
     72     strcpy(bin['7'], "0111");
     73     strcpy(bin['8'], "1000");
     74     strcpy(bin['9'], "1001");
     75     strcpy(bin['a'], "1010");
     76     strcpy(bin['b'], "1011");
     77     strcpy(bin['c'], "1100");
     78     strcpy(bin['d'], "1101");
     79     strcpy(bin['e'], "1110");
     80     strcpy(bin['f'], "1111");
     81 
     82     int kase = 0;
     83     while(scanf("%d%d", &h, &w) == 2 && h)
     84     {
     85         memset(picture, 0, sizeof(picture));
     86         for(int i = 0; i < h; ++i)
     87         {
     88             scanf("%s", s);
     89             for(int j = 0; j < w; ++j)
     90                 decode(i+1, j*4+1, s[j]);
     91         }
     92 
     93         h += 2;
     94         w = w * 4 + 2;
     95 
     96         int cnt = 0;
     97         vector<int> cc;
     98         memset(color, 0, sizeof(color));
     99         for(int i = 0; i < h; ++i)
    100             for(int j = 0; j < w; ++j)
    101                 if(!color[i][j])
    102                 {
    103                     DFS(i, j, ++cnt);
    104                     if(picture[i][j] == 1)    cc.push_back(cnt);
    105                 }
    106 
    107         neighbor.clear();
    108         neighbor.resize(cnt + 1);
    109         for(int i = 0; i < h; ++i)
    110             for(int j = 0; j < w; ++j)
    111                 if(picture[i][j] == 1)
    112                     check_neighbor(i, j);
    113 
    114         vector<char> ans;
    115         for(int i = 0; i < cc.size(); ++i)
    116             ans.push_back(recgonize(cc[i]));
    117         sort(ans.begin(), ans.end());
    118 
    119         printf("Case %d: ", ++kase);
    120         for(int i = 0; i < ans.size(); ++i)    printf("%c", ans[i]);
    121         printf("
    ");
    122     }
    123 
    124     return 0;
    125 }
    代码君
  • 相关阅读:
    windows red5相关
    redis集群及相关的使用
    c# 并行运算
    C# Thread
    html5网页录音
    netcore log4相关
    Swagger插件netcore配置
    MongoDB操作集
    .Net Core知识点
    C#中字典集合HashTable、Dictionary、ConcurrentDictionary三者区别
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3989724.html
Copyright © 2020-2023  润新知