这题是2011年的World finals的题目。
判断由01矩阵组成的图像是属于哪个古埃及的文字。从6个图形可以看出,每一个图形里面的 空洞 都是不同的。可以从空洞的个数来判断属于哪个文字。
矩阵组成的每一个文字都是完整的,两个文字之间不会有连接。题目的给是01矩阵每四位构成的十六进制的矩阵,需要转换一下,这个不难。
01矩阵外围再围上一圈 的 0,一开始进行一次深搜dfs(0,0),将每一个文字都分离出来。
再来矩阵中找到 数值为 1 的 地方,从该位置起进行一次深搜,遇到 0,深搜一次,空洞数 + 1。因为第一次深搜 把文字都分离了,所以不会互相干扰。
输出是按字典序输出的。
AC代码:
#include <iostream>
#include <cstring>
using namespace std;
int num[210][210];
int h, w, count;
int ans[8];
char str[] = {'A', 'D', 'J', 'K', 'S', 'W'};
int bin[][4] = {{0,0,0,0}, //0
{0,0,0,1}, //1
{0,0,1,0}, //2
{0,0,1,1}, //3
{0,1,0,0}, //4
{0,1,0,1}, //5
{0,1,1,0}, //6
{0,1,1,1}, //7
{1,0,0,0}, //8
{1,0,0,1}, //9
{1,0,1,0}, //a
{1,0,1,1}, //b
{1,1,0,0}, //c
{1,1,0,1}, //d
{1,1,1,0}, //e
{1,1,1,1}}; //f
bool cheak(int x, int y)
{
if((x >= 0 && x <= h + 1) && (y >= 0 && y <= w + 1))
return true;
else
return false;
}
void dfs(int x, int y)
{
if(!cheak(x, y) || num[x][y] != 0)
return;
num[x][y] = -1;
// cout << x << ' ' << y << endl;
dfs(x - 1, y);
dfs(x, y + 1);
dfs(x + 1, y);
dfs(x, y - 1);
}
void DFS(int x, int y)
{
if(!cheak(x, y) || num[x][y] == -1)
return;
if(num[x][y] == 0) //找到空洞
{
count++;
dfs(x, y);
return;
}
num[x][y] = -1;
DFS(x - 1, y);
DFS(x, y + 1);
DFS(x + 1, y);
DFS(x, y - 1);
}
int main()
{
freopen("1103.txt", "r", stdin);
int t = 0, i, j;
char ch;
while(cin >> h >> w)
{
if(h == 0 && w == 0)
break;
memset(num, 0, sizeof(num));
memset(ans, 0, sizeof(ans));
for(i = 0; i < h; i++)
{
for(j = 0; j < w; j++)
{
cin >> ch;
if(ch >= '0' && ch <= '9') //转换成二进制的
{
int l = 0;
for(int k = j * 4 + 1; k <= j * 4 + 4; k++)
num[i + 1][k] = bin[ch - '0'][l++];
} else if(ch >= 'a' && ch <= 'f')
{
int l = 0;
for(int k = j * 4 + 1; k <= j * 4 + 4; k++)
num[i + 1][k] = bin[ch - 'a' + 10][l++];
}
}
}
w = w * 4; //宽 * 4
dfs(0, 0); //分离文字
cout << "Case " << ++t << ": ";
for(i = 1; i <= h; i++)
{
for(j = 1; j <= w; j++)
{
if(num[i][j] == 1) //找到一个文字
{
count = 0;
DFS(i, j);
if(count == 0)
ans[5]++;
if(count == 1)
ans[0]++;
if(count == 2)
ans[3]++;
if(count == 3)
ans[2]++;
if(count == 4)
ans[4]++;
if(count == 5)
ans[1]++;
}
}
}
for(i = 0; i < 6; i++)
{
while(ans[i]--)
cout << str[i];
}
cout << endl;
}
return 0;
}