思路:对于每个黑像素的联通块,求出包含的白色区域有多少,根据包含白色区域的数目判断对应哪一种象形文字。
先用一遍DFS求出有多少个黑色联通块,并给每个联通块一个标号,该联通块里的每一个黑色节点都被标记上这个标号。
然后对白色的方格进行一遍DFS,目的是求出该白色联通块属于哪一个黑色联通块。求解的方法是:在白色DFS的过程中,如果遇到了一个黑色方格,那么就意味这这个白色联通块与这个黑色联通块相接,那么用一个set<int>记录一下。如果在白色DFS过程中遇到了边界,那么这个联通块是不要的,因为这必然是背景。如果该白色联通块不是背景并且只遇到了一个黑色联通块,那么对应的黑色联通块所包含的白色联通块数+1。最后根据每个黑色联通块所包含的白色区域数来判断这个联通块是什么符号,然后将结果字典序输出即可。(我的代码必须要在外围加上一圈白色的方格才能AC)
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <list>
#include <stack>
#include <queue>
#include <map>
#include <string>
#include <cctype>
#include <cmath>
#include <cstring>
#include <climits>
#include <complex>
#include <set>
#include <deque>
#define DEBUG(x) cerr<<"line:"<<__LINE__<<", "<<#x" == "<<(x)<<endl;
#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)
#define FOR(it,s) for(__typeof(s.begin()) it=s.begin();it!=s.end();it++)
#define ALL(a) (a).begin(),(a).end()
#define RALL(x) (a).rbegin(),(a).rend()
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define PB push_back
#define SZ(a) (int)(a).size()
using namespace std;
typedef long long LL;
typedef unsigned int uint;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<vi> vvi;
#define INF 1000000000
const double eps = 1e-10;
int dcmp(double x){
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
// ------------------
// author : onehrxn
// ------------------
const int maxn = 200 + 10;
int H, W;
struct node{
bool c;
int id;
};
node m[maxn][maxn];
int vis[maxn][maxn];
inline void to_bit(char tmp, int r, int c){
int num = 0;
if( '0' <= tmp && tmp <= '9') num = tmp - '0';
else num = tmp - 'a' + 10;
int tc[4];
int cur = 3;
for(int i = 0; i < 4; i++){
tc[cur] = num % 2;
cur--;
num /= 2;
}
for(int i = 0; i < 4; i++){
m[r][c*4 + i + 1].c = tc[i];
}
}
int dr[] = {-1, 0, 0, 1};
int dc[] = {0, -1, 1, 0};
inline bool ok(int r, int c){
if(r < 0 || r >= H + 2) return 0;
if(c < 0 || c >= W*4 + 2) return 0;
return 1;
}
int have[maxn];
void b_dfs(int r, int c, int id){
m[r][c].id = id;
vis[r][c] = 1;
for(int i = 0; i < 4; i++) {
int newr = r + dr[i], newc = c + dc[i];
if(ok(newr,newc) && (m[newr][newc].c==1) && (!vis[newr][newc]))
b_dfs(newr, newc, id);
}
}
set<int> meet_black;
bool w_dfs(int r, int c){
vis[r][c] = 1;
int flag = 1;
for(int i = 0; i < 4; i++){
int newr = r + dr[i], newc = c + dc[i];
if(ok(newr, newc)){
if(vis[newr][newc] && m[newr][newc].c == 1){ // meet the black
meet_black.insert(m[newr][newc].id);
}
else if(!vis[newr][newc] && m[newr][newc].c == 0){ // a new white
w_dfs(newr, newc);
}
}
else flag = 0;
}
return flag;
}
map<int, char> mp;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
#ifdef LOCAL
//freopen("input", "r", stdin);
//freopen("output", "w", stdout);
#endif
int kase = 1;
mp[1] = 'A'; mp[3] = 'J'; mp[5] = 'D'; mp[4] = 'S';
mp[0] = 'W'; mp[2] = 'K';
while(cin >> H >> W){
if(!H && !W) break;
MS0(m);
meet_black.clear();
char tmp;
for(int i = 1; i <= H; i++) {
for(int j = 0; j < W; j++) {
cin >> tmp;
to_bit(tmp, i, j);
}
}
for(int i = 0; i <= W*4 + 1; i++) m[0][i].c = 0;
for(int i = 0; i <= H + 1; i++) m[i][0].c = 0;
for(int i = 0; i <= H + 1; i++) m[i][W*4 + 1].c = 0;
for(int i = 0; i <= W*4 + 1; i++) m[H+1][i].c = 0;
// first get the black block and give all the black pixel an id
MS0(vis);
int cnt = 0;
for(int i = 0; i <= H + 1; i++) {
for(int j = 0; j <= 4*W + 1; j++) {
if(!vis[i][j] && m[i][j].c == 1) {b_dfs(i,j,cnt);cnt++;}
}
}
MS0(have);
for(int i = 0; i <= H + 1; i++){
for(int j = 0; j <= 4*W + 1; j++){
if(!vis[i][j] && m[i][j].c == 0) {
meet_black.clear();
if(w_dfs(i,j)){
if(meet_black.size() == 1){
FOR(it, meet_black){
have[*it]++;
}
}
}
else continue;
}
}
}
vector<char> ans;
for(int i = 0; i < cnt; i++) {
ans.PB(mp[have[i]]);
}
sort(ALL(ans));
cout << "Case " << kase++ << ": ";
FOR(it, ans) cout << *it;
cout << '\n';
//cout << res << '\n';
}
#ifdef LOCAL
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}