hdu 3839

Ancient Messages

题目大意:给出以下6种象形文字,编程识别出来。
figureC1

输入:有多组测试样例,每组测试样例使用0(白色像素) 和 1(黑色像素)来描述一张图片。出于节约空间的目的,使用1位16进制数 表示 4位二进制数。图片最大size为(50 200)。二进制解码之后实际大小为(200 200)

给出的测试样例符合以下条件:

  • 图片中只会出现 这6种象形文字
  • 图片中至少有一个象形文字存在
  • 每一个黑色像素都是一个象形文字的一部分(可以理解为文字笔画是标准的)
  • 黑色像素是拼接成了文字笔画
  • 文字之间不会有重叠 和 接触
  • 两颗黑色像素如果是对角接触,也可以认为这两个像素是同一个文字的一部分。(这个条件我貌似没在意,遍历只在乎 上左下右 四个方向)
  • 文字可能会比较潦草,但还是6个象形文字的符号结构

输出: 字母顺序 输出图片中的所有象形文字

思考:题目乍一看毫无头绪,但是观察这6种符号,就能发现一个明显的特征,每一种符号都有各自的“封闭区域”。

AnKh有1个“封闭区域”,Wedjat有3个“封闭区域”,Djed有5个“封闭区域”,Scarab有4个“封闭区域”,Was有0个“封闭区域”,Akeht有2个“封闭区域”。

我们可以对不同的“封闭区域”进行染色标记,再沿着黑色像素遍历,看能接触到多少种不同颜色的“封闭区域”。 如果有1种的话,那么所遍历的黑色像素 描绘的就是 Was符号了,以此类推

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// main.cpp
// hdu 3839
//
// Created by miaoyou.gmy on 15/8/29.
// Copyright (c) 2015年 miaoyou.gmy. All rights reserved.
//

#include <iostream>
#include <vector>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
const int H = 205;
const int W = 205;
int maze[H][W],h,w,colorCount;
bool colorVis[H],vis[H][W];
const int dir[4][2] = { {0,1},{1,0},{-1,0},{0,-1} };
const char hieroglyphMap[] = {'W','A','K','J','S','D'};

bool judge(const int x, const int y){
return (x>-1&&x<h&&y>-1&&y<w&&!vis[x][y]);
}

void dfs(int x,int y,int color){
maze[x][y] = color;
for(int i = 0; i < 4; i++){
int xx = x+dir[i][0];
int yy = y+dir[i][1];
if(judge(xx,yy) && !maze[xx][yy]){
vis[xx][yy] = true;
dfs(xx,yy,color);
}
}
}

void countDiffentColor(int x,int y){
for(int i = 0; i < 4; i++){
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if(judge(xx, yy)){
if(maze[xx][yy] != 1){
if(!colorVis[maze[xx][yy]]) colorCount++;
colorVis[maze[xx][yy]] = true;
}
else{
vis[xx][yy] = true;
countDiffentColor(xx, yy);
}
}
}
}



int main(int argc, const char * argv[]) {
int caseNumber = 1;
while(~scanf("%d%d",&h,&w)){
if(0 == h && 0 == w) break;
memset(maze, 0, sizeof(int) * H * W);
char strs[51];
for(int i = 0; i < h; i++){
scanf("%s",strs);
for(int j = 0; j < w; j++){
int tmp = 0;
if(strs[j]>='0' && strs[j]<='9') tmp = strs[j] - '0';
else tmp = 10+strs[j]-'a';

for(int k = 0; k < 4 ; k++){
maze[i+1][4*j+k+1] = ((tmp>>(3-k))&1);
}
}
}

h+=2, w*=4,w+=2;
int color = 2;
memset(vis, false, sizeof(bool) * H * W);
for(int i = 0; i < h; i++){
for(int j = 0; j < w; j++){
if(!maze[i][j]){
dfs(i,j,color);
color++;
}
}
}
vector<char> ans;
memset(vis, false, sizeof(bool) * H * W);
for(int i = 0; i < h; i++){
for(int j = 0; j < w; j++){
if(maze[i][j] == 1 && !vis[i][j]){
colorCount = 0;
memset(colorVis, false, sizeof(bool) * H);
countDiffentColor(i,j);
ans.push_back(hieroglyphMap[colorCount - 1]);
}
}
}
sort(ans.begin(), ans.end());
string str(ans.begin(),ans.end());
cout<<"Case "<<caseNumber++<<": "<<str<<endl;
}
return 0;
}

hdu-3839-accepted

如有任何知识产权、版权问题或理论错误,还请指正。

转载请注明原作者及以上信息。