
正文
[uva]AncientMessages象形文字识别 (dfs求连通块)
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
非常有趣的一道题目,大意是给你六种符号的16进制文本,让你转化成二进制并识别出来
代码实现上参考了//http://blog.csdn.net/u012139398/article/details/39533409
#include<cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set> using namespace std; const int MAXH = ;
const int MAXW = ;
int H,W;
int dx[] = {, , -, };
int dy[] = {, -, , };
char* bin[]= {"","","","","","","",""
,"","","","","","","",""};
char code[] = "WAKJSD"; char pic1[MAXH][MAXW];
char pic[MAXH][MAXW<<];
int color[MAXH][MAXW<<]; void dfs(int x,int y,int col)
{
color[x][y] = col;
for(int i = ; i < ; ++i){
int nx = x + dx[i], ny = y + dy[i];
if(nx >= && nx < H && ny >= && ny < W
&& pic[x][y] == pic[nx][ny] && !color[nx][ny])
dfs(nx,ny,col);
}
}
int main()
{
// freopen("in.txt","r",stdin);// FE
int cas = ;
while(scanf("%d%d",&H,&W),H){ memset(pic,,sizeof(pic));
memset(color,,sizeof(color)); for(int i = ; i < H; ++i)
scanf("%s",pic1[i]);
for(int i = ; i < H; ++i)
for(int j = ; j < W; ++j){
if(pic1[i][j]<=''&&''<=pic1[i][j])
pic1[i][j] -= '';
else
pic1[i][j] -= 'a' - ;
for(int k = ; k < ; ++k){//decode
pic[i+][+(j<<)+k] = bin[pic1[i][j]][k] - '';
}
} H += ;
W = (W<<)+;
vector<int> cc;
int cnt = ;//cnt = 1一定是白色背景
for(int i = ; i < H; ++i)
for(int j = ; j < W; ++j){
if(!color[i][j]) {
dfs(i,j,++cnt);
if(pic[i][j] == ) cc.push_back(cnt);//记录黑色所在的连通块 //!!没放到括号里
} } vector< set<int> > neigh(cnt+);
for(int i = ; i < H; ++i)
for(int j = ; j < W; ++j) {
if(pic[i][j]){
for(int k = ; k < ; ++k){
int x = i + dx[k], y = j + dy[k];
if(x >= && x < H && y >= && y < W
&& pic[x][y] == && color[x][y] != )
neigh[color[i][j]].insert(color[x][y]);
}
}
} vector<char> ans;
for(int i = ; i < cc.size(); ++i)
ans.push_back(code[neigh[cc[i]].size()]);
sort(ans.begin(),ans.end()); printf("Case %d: ",++cas);
for(int i = , sz = ans.size(); i < sz; ++i)
printf("%c",ans[i]);
puts("");
}
return ;
}







