题目链接:https://vjudge.net/problem/UVA-1103
题解:通过观察题目,所给的几个象形符号可以由每个图像所包围产生的洞洞来确定,统计dfs对图中的块进行染色,然后再统计每个图中的所包围的块数,其中比较坑的是将十六进制转为二进制以后,坐标会发生变化,然后会导致各种错误,我仔细改了好久才AC的。
代码:
#include<iostream>
#include<set>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn = 200 + 10;
string code[256];
int H, W;
int pic[maxn][maxn];
int color[maxn][maxn];
int dr[4] = { 0,0,1,-1 };
int dc[4] = { 1,-1,0,0 };
void dfs(int row, int col, int c) {
if (row < 0 || col < 3 || row > H+1 || col > 4*(W+1))return;
color[row][col] = c;
for (int i = 0; i < 4; i++) {
int r0 = row + dr[i];
int c0 = col + dc[i];
if (pic[r0][c0] == pic[row][col] && color[r0][c0] == 0) {
dfs(r0, c0, c);
}
}
}
int main() {
code['0'] = "0000";
code['1'] = "0001";
code['2'] = "0010";
code['3'] = "0011";
code['4'] = "0100";
code['5'] = "0101";
code['6'] = "0110";
code['7'] = "0111";
code['8'] = "1000";
code['9'] = "1001";
code['a'] = "1010";
code['b'] = "1011";
code['c'] = "1100";
code['d'] = "1101";
code['e'] = "1110";
code['f'] = "1111";
int kase = 0;
//freopen("input.txt","r",stdin);
while ((cin >> H >> W) && W && H) {
int cnt = 0;
vector<int> ss;
memset(color, 0, sizeof(color));
memset(pic, 0, sizeof(pic));
for (int i = 1; i <= H; i++) {
for (int j = 1; j <= W; j++) {
char ch;
cin >> ch;
for (int p = 0; p < 4; p++) {
pic[i][4 * j + p] = code[ch][p]-'0';
}
}
}
for (int i = 0; i <= H+1; i++) {
for (int j = 3; j <= (4*(W+1)); j++) {
if (color[i][j]==0) {
dfs(i, j, ++cnt);
if (pic[i][j] == 1)ss.push_back(cnt);
}
}
}
vector<set<int> > neighbor(cnt+1);
for (int i = 1; i <= H; i++) {
for (int j = 4; j <= (4*(W+1)-1); j++) {
if (pic[i][j] == 1) {
for (int p = 0; p < 4; p++) {
int r = i + dr[p];
int c = j + dc[p];
if (r >= 1 && r <= H&&c >= 4 && c <= (4*(W+1)-1)&&pic[r][c] == 0 && color[r][c] != 1) {
neighbor[color[i][j]].insert(color[r][c]);
}
}
}
}
}
string words = "WAKJSD";
vector<char> output;
for (int i = 0; i < ss.size(); i++) {
output.push_back(words[neighbor[ss[i]].size()]);
}
sort(output.begin(), output.end());
cout << "Case " << ++kase << ": ";
for (int i = 0; i < output.size(); i++)
cout << output[i];
cout << endl;
}
return 0;
}