Uva1103 Ancient Messages

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

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

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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

//0表示空白位置,-1表示不能访问了.

const int maxn = 510;

int n, m,kase,a[maxn][maxn],flag[maxn][maxn],cnt,num[maxn];
char s16[] = { ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘ };
char fuhao[6] = { ‘A‘, ‘D‘, ‘J‘, ‘K‘, ‘S‘, ‘W‘ };
int s2[16][4] =
{
    { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 0, 1, 0 }, { 0, 0, 1, 1 },
    { 0, 1, 0, 0 }, { 0, 1, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 1 },
    { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, { 1, 0, 1, 0 }, { 1, 0, 1, 1 },
    { 1, 1, 0, 0 }, { 1, 1, 0, 1 }, { 1, 1, 1, 0 }, { 1, 1, 1, 1 }
};

void dfs1(int x,int y)
{
    if (x < 0 || x > n + 1 || y < 0 || y > m + 1 || a[x][y] != 0)
        return;
    a[x][y] = -1;
    dfs1(x - 1, y);
    dfs1(x + 1, y);
    dfs1(x, y - 1);
    dfs1(x, y + 1);
}

void dfs2(int x, int y)
{
    if (x < 0 || x > n + 1 || y < 0 || y > m + 1 || a[x][y] == -1)
        return;
    if (a[x][y] == 0)
    {
        cnt++;
        dfs1(x, y);
        return;
    }
    a[x][y] = -1;
    dfs2(x - 1, y);
    dfs2(x + 1, y);
    dfs2(x, y - 1);
    dfs2(x, y + 1);
}

int main()
{
    while (scanf("%d%d", &n, &m) == 2 && (n || m))
    {
        memset(a, 0, sizeof(a));
        memset(num, 0, sizeof(num));
        for (int i = 1; i <= n; i++)
        {
            getchar();
            char ch;
            int tot = 0;
            for (int j = 1; j <= m; j++)
            {
                scanf("%c", &ch);
                for (int k = 0; k < 16; k++)
                {
                    if (ch == s16[k])
                    {
                        for (int l = 0; l < 4; l++)
                            a[i][++tot] = s2[k][l];
                        break;
                    }
                }
            }
        }
        m *= 4;
        dfs1(0, 0);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if (a[i][j] == 1)
                {
                    cnt = 0;
                    dfs2(i, j);
                    if (cnt == 0)
                        num[5]++;
                    if (cnt == 1)
                        num[0]++;
                    if (cnt == 2)
                        num[3]++;
                    if (cnt == 3)
                        num[2]++;
                    if (cnt == 4)
                        num[4]++;
                    if (cnt == 5)
                        num[1]++;
                }
        printf("Case %d: ", ++kase);
        for (int i = 0; i <= 5; i++)
        {
            while (num[i]--)
                printf("%c", fuhao[i]);
        }
        printf("\n");
    }

    return 0;
}
时间: 2024-10-07 06:39:27

Uva1103 Ancient Messages的相关文章

UVA1103 Ancient Messages 题解

每组数据包含一个H行W列的字符矩阵(H≤200,W≤50),每个字符为4个相邻像素点的十六进制(例如,10011100对应的字就是9c).转化为二进制后1表示黑点,0表示白点.输入满足: - 不会出现上述6种符号之外的其他符号. - 输入至少包含一个符号,且每个黑像素都属于一个符号. - 每个符号都是一个四连块,并且不同符号不会相互接触,也不会相互包含. - 如果两个黑像素有公共顶点,则它们一定有一个相同的相邻黑像素(有公共边). - 符号的形状一定和表中的图形拓扑等价(可以随意拉伸但不能拉断)

K - Ancient Messages(dfs求联通块)

K - Ancient Messages Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 1103 Appoint description: Description In order to understand early civilizations, archaeologists often study texts written in ancie

Ancient Messages UVA - 1103

题目链接:https://vjudge.net/problem/UVA-1103 题目大意:每组数据包含H行W列的字符矩阵(H<=200,W<=50) 每个字符为为16进制  你需要把它转化为二进制.  转化为二进制之后 1代表黑点 0代表白点 问你出现的所有符号  并按字典序输出! 思路:首先看到这道题,完全没看懂题意 ,真的没看懂,后来搜了题解才看明白题意,但是还是不会做,这道题是在紫书上看到的,紫书上并没有给出代码,学了别人的博客! 好了  具体怎么做呢? 仔细观察可以发现,每个字符中出

UVa 1103 (利用连通块来判断字符) Ancient Messages

本题就是灵活运用DFS来求连通块来求解的. 题意: 给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符.然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号. 分析: 首先图像是被压缩过的,所以我们要把它解码成一个01矩阵.而且我们还要在原图像的四周加一圈白边,这样图中的白色背景都连通起来了. 黑色连通块的个数就是字符的个数. 观察题中字符样式可知,每种字符中包裹的“白洞”的个数是不同的,所以我们可以根据每个字符中的“白洞”的个数来区别这些字符. 然后我们给所有的连通块染色,

UVA 1103 Ancient Messages (DFS)

起初学习dfs的时候 看不懂这个题目  回过头来今天看的时候思路相对比较清晰了.但还是想不到怎么处理 查询有多少个空白洞.并且一个图中还有好多个象形字符.网上思路是 在周围扩展一圈0,使得文字之外的所有0 都连通,一次dfs标记所有文字之外的0为-1.然后遍历图,发现1就沿着有1 的路径dfs2,在这个过程中,如果发现0,那么必然是文字内部的空洞,此时把空洞dfs 置为-1,标记以后不再走.那么发现几次0就有几个空洞在文字中.那么每一次的dfs2,就处理了一个象形文字.cnt的值就是空洞的个数即

uva 1103 - Ancient Messages(象!形!文!字! dfs遍历计数)

我今天做的这叫什么题-- 今天这个题直接跪了,一看十六进制直接懵了.. 然后在csdn上竟然发现了身边直系学长写的解题报告,然后问了一下解题的思路.然后写出来的代码,想要测试数据吗吧哈哈 给一组最基本的~ 5 3 fff f0f fff f0f fff 输出应该是K AC代码如下: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace

LRJ-Example-06-13-Uva1103

pic[][]数组存储每个点的值,0或1,输入时在原图的周围加了一圈0. color[][]数组存储每个点的color值,从1开始,dfs(row, col, c) 负责对每个点着色,连通在一起的连通块的颜色相同. 因为最先着色的是最外围的白色点,即background white,这些点的color值是1. neighbour[]数组的下标是color值,内容是一个set,存储下标color所代表的连通块周围的连通块的颜色,background white这个连通块不算. 比如 1. 测试用例

poj 2159 D - Ancient Cipher 文件加密

Ancient Cipher Description Ancient Roman empire had a strong government system with various departments, including a secret service department. Important documents were sent between provinces and the capital in encrypted form to prevent eavesdropping

uva--1339 - Ancient Cipher(模拟水体系列)

1339 - Ancient Cipher Ancient Roman empire had a strong government system with various departments, including a secret service department. Important documents were sent between provinces and the capital in encrypted form to prevent eavesdropping. The