Uva1103 Ancient Messages

时间:2024-09-09 22:37:44

题意:识别图中的象形文字。但是,图形可以任意的拉伸,但不能拉断。

分析:这种题如果图形没有特征是不可做类型的题,不过观察图形可以发现每个图形中的洞的数量是一定的,我们只需要数出每一个封闭图形的洞数就能知道这是哪个图形.

虽然知道了原理,但是并不是特别好做,首先我们需要一次dfs将所有图形旁边的点全都变为“不可访问”,然后从每个黑点开始枚举,向四周扩展,遇到白色的块就用第一次的dfs函数覆盖,否则继续第二次dfs,两次dfs交错使用,思路比较巧妙.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; //0表示空白位置,-1表示不能访问了. const int maxn = ; int n, m,kase,a[maxn][maxn],flag[maxn][maxn],cnt,num[maxn];
char s16[] = { '', '', '', '', '', '', '', '', '', '', 'a', 'b', 'c', 'd', 'e', 'f' };
char fuhao[] = { 'A', 'D', 'J', 'K', 'S', 'W' };
int s2[][] =
{
{ , , , }, { , , , }, { , , , }, { , , , },
{ , , , }, { , , , }, { , , , }, { , , , },
{ , , , }, { , , , }, { , , , }, { , , , },
{ , , , }, { , , , }, { , , , }, { , , , }
}; void dfs1(int x,int y)
{
if (x < || x > n + || y < || y > m + || a[x][y] != )
return;
a[x][y] = -;
dfs1(x - , y);
dfs1(x + , y);
dfs1(x, y - );
dfs1(x, y + );
} void dfs2(int x, int y)
{
if (x < || x > n + || y < || y > m + || a[x][y] == -)
return;
if (a[x][y] == )
{
cnt++;
dfs1(x, y);
return;
}
a[x][y] = -;
dfs2(x - , y);
dfs2(x + , y);
dfs2(x, y - );
dfs2(x, y + );
} int main()
{
while (scanf("%d%d", &n, &m) == && (n || m))
{
memset(a, , sizeof(a));
memset(num, , sizeof(num));
for (int i = ; i <= n; i++)
{
getchar();
char ch;
int tot = ;
for (int j = ; j <= m; j++)
{
scanf("%c", &ch);
for (int k = ; k < ; k++)
{
if (ch == s16[k])
{
for (int l = ; l < ; l++)
a[i][++tot] = s2[k][l];
break;
}
}
}
}
m *= ;
dfs1(, );
for (int i = ; i < n; i++)
for (int j = ; j < m; j++)
if (a[i][j] == )
{
cnt = ;
dfs2(i, j);
if (cnt == )
num[]++;
if (cnt == )
num[]++;
if (cnt == )
num[]++;
if (cnt == )
num[]++;
if (cnt == )
num[]++;
if (cnt == )
num[]++;
}
printf("Case %d: ", ++kase);
for (int i = ; i <= ; i++)
{
while (num[i]--)
printf("%c", fuhao[i]);
}
printf("\n");
} return ;
}