[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 = 210;
const int MAXW = 65;
int H,W;
int dx[] = {0, 0, -1, 1};
int dy[] = {1, -1, 0, 0};
char* bin[16]= {"0000","0001","0010","0011","0100","0101","0110","0111"
,"1000","1001","1010","1011","1100","1101","1110","1111"};
char code[7] = "WAKJSD";

char pic1[MAXH][MAXW];
char pic[MAXH][MAXW<<2];
int color[MAXH][MAXW<<2];

void dfs(int x,int y,int col)
{
   color[x][y] = col;
   for(int i = 0; i < 4; ++i){
      int nx = x + dx[i], ny = y + dy[i];
      if(nx >= 0 && nx < H && ny >= 0 && 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 = 0;
    while(scanf("%d%d",&H,&W),H){

      memset(pic,0,sizeof(pic));
      memset(color,0,sizeof(color));

      for(int i = 0; i < H; ++i)
         scanf("%s",pic1[i]);
      for(int i = 0 ; i < H; ++i)
         for(int j = 0; j < W; ++j){
            if(pic1[i][j]<='9'&&'0'<=pic1[i][j])
               pic1[i][j] -= '0';
            else
               pic1[i][j] -= 'a' - 10;
            for(int k = 0; k < 4; ++k){//decode
               pic[i+1][1+(j<<2)+k] = bin[pic1[i][j]][k] - '0';
            }
         }

      H += 2;
      W = (W<<2)+2;
      vector<int> cc;
      int cnt = 0;//cnt = 1一定是白色背景
      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] == 1) cc.push_back(cnt);//记录黑色所在的连通块 //!!没放到括号里
            }

         }

      vector< set<int> > neigh(cnt+1);
      for(int i = 0 ; i < H; ++i)
         for(int j = 0; j < W; ++j) {
            if(pic[i][j]){
               for(int k = 0; k < 4; ++k){
                  int x = i + dx[k], y = j + dy[k];
                   if(x >= 0 && x < H && y >= 0 && y < W
                     && pic[x][y] == 0 && color[x][y] != 1)
                     neigh[color[i][j]].insert(color[x][y]);
               }
            }
         }

      vector<char> ans;
      for(int i = 0 ; i < cc.size(); ++i)
         ans.push_back(code[neigh[cc[i]].size()]);
      sort(ans.begin(),ans.end());

      printf("Case %d: ",++cas);
        for(int i = 0, sz = ans.size(); i < sz; ++i)
            printf("%c",ans[i]);
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4596903.html