UVA 1103 Ancient Messages dfs
来源:互联网 发布:邱少云违背生理学知乎 编辑:程序博客网 时间:2024/05/16 12:21
按照《算法竞赛入门经典》的思路,我们只需要判断出当前文字有几个“洞”,就可以确定到底是哪个文字了。
W:零个洞
A:一个洞
K:两个洞
J:三个洞
S:四个洞
D:五个洞
本题重点就是如何判断一个文字有几个洞。我们知道每一个文字都是由很多个 "1" 组成的,背景是 “0”。
请看下面这个文字:
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
虽然看的眼花,但还是很容易就看出来这是文字 A,因为它只有一个洞。我们用程序该怎么判断呢?
相信读者都会用 dfs 判连通块,并且给连通块染色吧!
先用 dfs 把上图的连通块找出来,并染色。假设我们用了三种颜色分别是1, 2, 3,那么染色之后的图片就变成了:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1
1 1 1 1 2 2 2 2 3 3 3 3 2 2 2 2 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
1 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 2 2 2 2 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
现在有两张图片,一张未染色,一张已染色。
现在我们在未染色的图片中逐一检查 “1” 元素(从染色图片中可以看出来,所有的 “1” 元素都是颜色 2),看它上下左右四个方向有没有 “0” 元素,如果有的话,假设当前 “0” 元素的颜色是1,我们把颜色 1 放到一个集合set 中。
按照这样的方法,检查完所有的 “1” 之后,集合 set 中就有两个元素了,分别是 1,3。
这样我们就可以知道颜色为 2 的连通块邻接着颜色为 1 和颜色为 3 的连通块,也就是颜色为 2 的连通块有 1 个洞!通过这样的方法我们就可以判断一个文字有几个洞了。
因为实际中会有多个文字,所以我们要创建一个元素是 set 的 vector。
假如这个 vector 的名字叫做 adjacent,那么adjacent[i] 就表示和颜色为 i 的连通块邻接的连通块的颜色的集合。
当我们在检查颜色为 i 的 “1” 元素时,如果在上下左右四个方向找到了一个 “0” 元素,就将这个 “0” 元素的颜色放到 adjacent[i] 中去。
这道题的大致思路就是如此。不过在将16进制数字转化成2进制数字的时候也用了一个巧妙的方法,具体看代码吧,相信仔细看可以看懂的!
ps:在输入过程中要将图片拓展,上下左右各添加一行。至于为什么?看了下面这组数据你就懂了。
0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0
代码如下:
#include <set>#include <cmath>#include <cstdio>#include <vector>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;typedef long long int ll;const char* Hexadecimal[16] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};int pic[205][205], color[205][205];char table[10] = "*WAKJSD";int dx[] = {-1, 1, 0, 0};int dy[] = {0, 0, -1, 1};int H, W;// 判断坐标是否越界bool is_legal(int x, int y){ return x >= 0 && x < H && y >= 0 && y < W;}// dfs染色void dfs(int x, int y, int c){ color[x][y] = c; for (int d = 0; d < 4; d++) { int xx = x + dx[d], yy = y + dy[d]; if (is_legal(xx, yy) && pic[xx][yy] == pic[x][y] && !color[xx][yy]) dfs(xx, yy, c); }}int main(){ //freopen("1.txt", "r", stdin); int Case = 1; while (~scanf("%d%d", &H, &W) && H && W) { memset(pic, 0, sizeof(pic)); memset(color, 0, sizeof(color)); // 输入过程中将图片上下左右额外拓展了一行“0” for (int i = 1; i <= H; i++) { getchar(); for (int j = 1; j <= W; j++) { char c = getchar(); for (int k = 0; k < 4; k++) { if (c >= '0' && c <= '9') pic[i][k + (j - 1) * 4 + 1] = Hexadecimal[c - '0'][k] - '0'; else pic[i][k + (j - 1) * 4 + 1] = Hexadecimal[c - 'a' + 10][k] - '0'; } } } W = W * 4 + 2; H += 2; int cnt = 1; // 不能设为0,否则第一个连通块会被认为没染色 vector<int> BlackNumber; // 保存着黑色连通块的编号 for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { if (!color[i][j]) { dfs(i, j, cnt++); if (pic[i][j]) BlackNumber.push_back(cnt - 1); } } vector<set<int>> adjacent(205); for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { if (pic[i][j]) { for (int d = 0; d < 4; d++) { int x = i + dx[d], y = j + dy[d]; if (is_legal(x, y) && !pic[x][y]) adjacent[color[i][j]].insert(color[x][y]); // 将相邻连通块的颜色都放到set中去 } } } vector<char> ans; for (unsigned int i = 0; i < BlackNumber.size(); i++) { int c = BlackNumber[i]; int t = adjacent[c].size(); ans.push_back(table[t]); } sort(ans.begin(), ans.end()); printf("Case %d: ", Case++); for (unsigned int i = 0; i < ans.size(); i++) cout << ans[i]; cout << endl; } return 0;}
- UVA 1103 Ancient Messages DFS
- UVA 1103 Ancient Messages (DFS)
- UVa 1103 Ancient Messages (DFS)
- UVA 1103 Ancient Messages dfs
- UVa 1103 - Ancient Messages(DFS:Floodfill)
- UVa 1103 - Ancient Messages (DFS)
- UVA - 1103 Ancient Messages dfs+stl
- UVA-1103- Ancient Messages
- Uva - 1103 - Ancient Messages
- uva 1103 Ancient Messages
- UVA 1103 Ancient Messages
- UVA-1103 Ancient Messages
- UVa 1103 - Ancient Messages [进制转换+DFS]
- UVa 1103 - Ancient Messages [进制转换+DFS]
- uva 1103 Ancient Messages WA
- uva 1103 Ancient Messages (古象形文字)
- uva 1103 - Ancient Messages(象!形!文!字! dfs遍历计数)
- HDU-3839-Ancient Messages(DFS)
- 每日一题 No.35 五一劳动节快乐~
- gzip
- hdu 1024 Max Sum Plus Plus(最大m段子序列和)
- 反转字符串
- Oracle 约束的增删
- UVA 1103 Ancient Messages dfs
- ArcGIS Python API获取以及对比landsat数据
- float的影响
- POJ2828 Buy Tickets(线段树,单点更新)
- jQuery来了--进行CSS操作的方法(添加/删除类),CSS()方法
- poj2635(素数表)
- 第八周 bfs
- 二分查找
- HDU1005 Number Sequence