UVA-1103 Ancient Messages

来源:互联网 发布:cad 布局 知乎 编辑:程序博客网 时间:2024/04/30 12:30

Ancient Messages(紫书例6-13)

UVA - 1103

给定H行W列的十六进制数据,每个十六进制数表示4位二进制数,由此形成H行W*4列的二进制图,

有6种不同的古代象形文字,在图中以11110000......的形式表现出来,并且与给定的原始图拓扑相等(几个图形,其中每一个可以从其余任一个图形经扭转、弯曲、拉长或收缩得到,而不出现任何点的重叠与断开,它们就是拓扑等价的),

要求识别出图中出现的古代象形文字的种类与个数,并按照字母表顺序输出。

先把16进制数图转换为2进制数图,

再对原图中四边附近的空白部分(0)进行覆盖(-1),

区别六种象形文字的特征量是他们中间的空白部分个数,因此,每用DFS检测到一个象形文字(1),就统计其中空白部分(0)的个数,统计完后都覆盖掉(-1),由此得到每种象形文字的个数,然后按字母表序输出。

坑:输入输出和进制转化比较繁琐,要小心低级错误;

        计数步骤注意细节;

        将图四周的空白部分覆盖时,不要想当然。。。

AC-Code (C++)

Time: 10 ms

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<cstring>#include<string>#include<vector>#include<queue>#include<stack>#include<deque>#include<functional>using namespace std;const int MAXH = 200 + 10;int g[MAXH][MAXH];//保存图int H, W;//十六进制图案的行,列int kase = 1;int cnt = 0;int res[6];bool isin(int x, int y){return (x >= 0 && x < H && y >= 0 && y < W);}int input1[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 input2[16] = { '0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };char output[6] = { 'A', 'D', 'J', 'K', 'S', 'W' };//把联通的空白块涂成灰色void dfs(int x, int y){if ((!isin(x, y) )|| g[x][y] != 0)return;g[x][y] = -1;dfs(x - 1, y);dfs(x + 1, y);dfs(x, y - 1);dfs(x, y + 1);}//把黑块涂成灰色,如果发现白块,计数加一并调用dfs把连通的白块涂成灰色void dfs2(int x, int y){if ((!isin(x, y)) || g[x][y] == -1)return;if (g[x][y] == 0){cnt++;dfs(x, y);return;}g[x][y] = -1;dfs2(x - 1, y);dfs2(x + 1, y);dfs2(x, y - 1);dfs2(x, y + 1);}int main(void){while (scanf("%d %d", &H, &W) && H){memset(g, 0, sizeof(g));memset(res, 0, sizeof(res));char str[MAXH];for (int i = 0; i < H; i++){scanf("%s", str);for (int j = 0; j < W; j++){char ch = str[j];for (int ii = 0; ii < 16; ii++){if (ch == input2[ii]){for (int k = 0; k < 4; k++){g[i][j * 4 + k] = input1[ii][k];}}}}}W =W * 4;               //将图的四周的空白部分都填满for (int i = 0; i < H; i++){if (g[i][0] == 0)dfs(i, 0);if (g[i][W - 1] == 0)dfs(i, W - 1);}for (int j = 0; j < W; j++){if (g[0][j] == 0)dfs(0, j);if (g[H - 1][j] == 0)dfs(H - 1, j);}for (int i = 0; i < H; i++){for (int j = 0; j < W; j++){if (g[i][j] == 1){cnt = 0;dfs2(i, j);switch (cnt){case 0:res[5]++; break;case 1:res[0]++; break;case 2:res[3]++; break;case 3:res[2]++; break;case 4:res[4]++; break;case 5:res[1]++; break;}}}}printf("Case %d: ", kase++);for (int i = 0; i < 6; i++){for (int j = 0; j < res[i]; j++){printf("%c", output[i]);}}printf("\n");}return 0;}