题目链接https://vjudge.net/problem/UVA-1103
通过计算图案内部空心的个数来确定字母,为了区分外面的空心,我们可以在外面加上一层0,先对外面进行一次DFS
代码是看了别人的代码之后写的,多看别人优秀的代码也是一种好的学习方式
另外代码中用到了memcpy函数
可以在这篇博客中找到它的用法和源码https://blog.csdn.net/xiaominkong123/article/details/51733528/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
const int N = 200;
const string dict[16] =
{
"0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111",
}; //方便一会将16进制转化为2进制
const int dir[4][2] = { {-1,0}, {0,-1}, {1,0}, {0,1} }; //DFS扩展需要
const char alpha[8] = { 'W', 'A', 'K', 'J', 'S', 'D' }; //字母下标就是字符的白洞的个数
map<char, int> cnt; //存储图中的字符
char tab[N + 10][N + 10];
int H, W, cur, kcase; //H为行数,W为列数
bool isin(int x, int y)
{
return x >= 0 && x <= H + 1 && y >= 0 && y <= W + 1;
}
void DFS1(int x, int y) //对白色区域DFS
{
if (tab[x][y] != '0' || !isin(x, y)) return;
tab[x][y] = '-';
for (int i = 0; i < 4; i++) {
int dx = x + dir[i][0], dy = y + dir[i][1];
DFS1(dx, dy);
}
}
void DFS2(int x, int y) //黑色区域DFS
{
if (tab[x][y] != '1' || !isin(x, y)) return;
tab[x][y] = '-';
for (int i = 0; i < 4; i++) {
int dx = x + dir[i][0], dy = y + dir[i][1];
if (tab[dx][dy] == '0') cur++, DFS1(dx, dy); //如果遇到白色,则对白色进行DFS,白洞数加1
else DFS2(dx, dy); //否则继续扩展黑色
}
}
int main()
{
kcase = 0;
while (memset(tab, '0', sizeof(tab)), cnt.clear(), cin >> H >> W, H || W)
{
W *= 4;
for (int i = 1; i <= H; i++) {
string line, res; cin >> line;
for (auto it : line) res += dict[it >= 'a' ? it - 'a' + 10 : it - '0']; //转化为二进制表示形式
memcpy(tab[i] + 1, res.c_str(), W);
}
DFS1(0, 0);
for(int i=1;i<=H;i++)
for (int j = 1; j <= W; j++) {
if (tab[i][j] != '1') continue;
cur = 0;
DFS2(i, j);
cnt[alpha[cur]]++;
}
printf("Case %d: ",++kcase);
for (auto it : cnt) while (it.second--) cout << it.first;
puts("");
}
}