UVA 1103 Ancient Messages (DFS)

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

有一处值得学习的地方,字符串常量的运用。

奇怪的地方时在hdu oj上提交 是栈溢出,而在uva上却过了。

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int INF=210;
int n,m,cnt;

char cn[6]= {'A','D','J','K','S','W'};
char str[]= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
int dir[][4]= {{-1,0},{0,-1},{1,0},{0,1}};
int G[INF][INF];

int s[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 input()
{

    char ch;
    memset(G,0,sizeof(G));
    for(int i=1; i<=n; i++)
    {
        getchar();
        int len=1;
        for(int j=1; j<=m; j++)
        {
            scanf("%c",&ch);
            for(int k=0; k<16; k++)
            {
                if(ch==str[k])
                {
                    for(int t=0; t<4; t++)
                        G[i][len++]=s[k][t];
                    break;
                }

            }
        }
    }

}

bool inG(int x,int y)
{
    if(x>=0&&x<=n+1&&y>=0&&y<=m+1)
        return 1;
    return 0;
}

void dfs(int x,int y)
{
    if(!inG(x,y)||G[x][y]!=0)
        return ;
    G[x][y]=-1;
    for(int i=0; i<4; i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        dfs(tx,ty);
    }

}

void dfs2(int x,int y)
{
    if(!inG[x][y]||G[x][y]==-1)
        return ;
    if(!G[x][y])
    {
        dfs(x,y);
        cnt++;

        return ;
    }
    G[x][y]=-1;
    for(int i=0; i<4; i++)
    {
        int tx=x+dir[i][0];
        int ty=y+dir[i][1];
        dfs2(tx,ty);

    }
}

int main()
{
    int ca=1;
    int num[10];
    while(scanf("%d%d",&n,&m)==2&&n+m)
    {
        memset(G,0,sizeof(G));
        memset(num,0,sizeof(num));
        input();
        m*=4;
        dfs(0,0);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(G[i][j]==1)
                {
                    cnt=0;
                    dfs2(i,j);
                    if(cnt==0)
                        num[5]++;
                    else if(cnt==2)
                        num[3]++;
                    else if(cnt==3)
                        num[2]++;
                    else if(cnt==4)
                        num[4]++;
                    else if(cnt==1)
                        num[0]++;
                    else num[1]++;
                }
            }
        }
        printf("Case %d: ",ca++);
        for(int i=0; i<6; i++)
            while(num[i]--)
                printf("%c",cn[i]);
        printf("\n");
    }
    return 0;
}
时间: 2024-12-24 09:10:20

UVA 1103 Ancient Messages (DFS)的相关文章

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

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

图-用DFS求连通块 UVa 1103

这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者耐心细读.(也许由于博主太弱, 才有此等感觉). 题目: UVa 1103 In order to understand early civilizations, archaeologists often study texts written in  ancient languages. One

uva 1103

#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #include <cstdlib> #include <stack> #include <cctype> #include <string> #include <malloc.h> #include

HDU-3839-Ancient Messages(DFS)

Problem Description In order to understand early civilizations, archaeologists often study texts written in ancient languages. One such language, used in Egypt more than 3000 years ago, is based on characters called hieroglyphs. Figure C.1 shows six

uva 1339 Ancient Cipher(字符串处理)

uva 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. T

UVa 572 Oil Deposits(DFS)

 Oil Deposits  The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots.

UVA 10318 - Security Panel dfs 剪枝

UVA 10318 - Security Panel dfs 剪枝 ACM 题目地址:UVA 10318 - Security Panel 题意: 这题跟点灯的题目很像,点灯游戏选择一盏灯时会让它以及四周的灯改变状态. 但是我们有特殊的开开关技巧,它给出了改变状态的位置,而不是四周都改变. 问你从全部关着变成全部开着的最小开关步骤. 分析: 很明显,在一个位置上点两次或更多次是没有必要的,所以一个位置只有选择与不选择,用dfs即可,但如果暴力所有可能,复杂度是2^25,会超时,所以要剪枝. 由于

UVa 1339 Ancient Cipher --- 水题

UVa 1339 题目大意:给定两个长度相同且不超过100个字符的字符串,判断能否把其中一个字符串重排后,然后对26个字母一一做一个映射,使得两个字符串相同 解题思路:字母可以重排,那么次序便不重要,可以分别统计两个字符串中的各个字母出现的次数,得到两个cnt[26]数组, 又由于可以进行映射,则可以直接对两个数组进行排序后判断是否相等(相当于原来相等的值的两个地方做映射) /* UVa 1339 Ancient Cipher --- 水题 */ #include <cstdio> #incl