[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;//sb la  W+=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;

}

 

你可能感兴趣的:(message)