欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Uva 1103 Ancient Messages

程序员文章站 2022-04-02 10:05:38
...

大致思路是DFS:

  1. 每个图案所包含的白色连通块数量不一:

      Ankh : 1 ;  Wedjat : 3  ; Djed : 5   ;   Scarab : 4 ; Was : 0  ;  Akeht : 2

  根据每个图包含的白色连通块判断是哪个图案

  2. 两个Dfs函数,一个判断白色,一个判断黑色;判断黑色的Dfs,一旦发现白色,就调用判断白色的Dfs,同时白色连通块计数器加一

  3. 我开始比较疑惑的一个地方是:如何判断这个白色块是在一个黑色图案里面还是外面?后来才明白:只要一开始在图外面再加一层白色框框,然后开始访问白色,把此时访问到的所有白色设为不可访问即可,这样子就不会把图案里面的白色连通块和外面的混淆了

 

一点感悟和收获:这题确实再某种程度上刷新了我“的世界观“,初看题意,啥想法都没有,后来再看看书,再看看别人的题解,才发现,这题实在太简单了!说白了,一开始把题目想复杂了,没发现浅显的规律,如果能静下心来,仔细发现规律的话,这题真的比我最初想像的简单太多了!

 

参考资料:

  1. http://www.cnblogs.com/hanbinggan/p/4225044.html

  2. 《算法竞赛入门经典(第二版)》

 

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 200 + 10;
int plan[MAXN][MAXN];
int counter[MAXN];
char apl[] = "ADJKSW";
int H, W;

void Read() {
    memset(plan, 0, sizeof(plan));
    char c;
    int pos;
    for(int i=1; i<=H; i++) {
        pos = 1;
        for(int j=1; j<=W; j++) {
            cin >> c;
            if(isalpha(c)) {
                c = c - 'a' + 10;
            } else {
                c = c - '0';
            }
            // Transfer to binary
            pos += 3;
            for(int k=0; k<4; k++) {
                plan[i][pos --] = c % 2;
                c /= 2;
            }
            pos +=5;
        }
    }
    W *= 4;
}

bool Inside(int x, int y) {
    return x>=0 && x<=H+1 && y>=0 && y<=W+1;
}

int cnt;
void DfsWhite(int x, int y) {
    if(!Inside(x, y) || plan[x][y]!=0) {
        return ;
    }
    plan[x][y] = -1;
    DfsWhite(x, y+1);
    DfsWhite(x, y-1);
    DfsWhite(x+1, y);
    DfsWhite(x-1, y);
}

void DfsBlack(int x, int y) {
    if(!Inside(x, y) || plan[x][y] == -1) return ;
    if(plan[x][y] == 0) {
        ++ cnt;
        DfsWhite(x, y);
        return ;
    }
    plan[x][y] = -1;
    DfsBlack(x, y+1);
    DfsBlack(x, y-1);
    DfsBlack(x+1, y);
    DfsBlack(x-1, y);
}

int Case = 0;
void Work() {
    Read();
    DfsWhite(0, 0); // the white blocks outside the hieroglyphs
    memset(counter, 0, sizeof(counter));
    for(int i=1; i<=H; i++) {
        for(int j=1; j<=W; j++) {
            if(plan[i][j] == 1) {
                cnt = 0;
                DfsBlack(i, j);
                switch(cnt) {
                    case 0: counter['W'] ++; break;
                    case 1: counter['A'] ++; break;
                    case 2: counter['K'] ++; break;
                    case 3: counter['J'] ++; break;
                    case 4: counter['S'] ++; break;
                    case 5: counter['D'] ++; break;
                }
            }
        }
    }
    cout << "Case " << (++Case) << ": ";
    for(int i=0; i<6; i++) {
        for(int j=0; j<counter[apl[i]]; ++j) {
            cout << apl[i];
        }
    }
    cout << endl;
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    while(cin >> H >> W && (H + W)) {
        Work();
    }
    return 0;
}