题目链接:

https://www.luogu.org/problemnew/show/UVA1103

题目分析:

我们可以先进行矩阵的还原

for(int k=1;k<=4;k++)
{
a[i][++cnt]=(tmp>>(4-k))&1;
}

这种使用for语句的方法在其他题解内貌似没有提及,(但其实就是把anguei的化简了一下)

这样就能复原出原始的数据(01矩阵)

然后我们可以发现每一个象形文字都有可放缩性,但空白的个数是一定的。例如虫子图案就有4个空白处。

这样我们可以利用这一特性来解决问题了。

接下来用的算法是dfs乃至bfs入门都很常见的经典模型——水洼(或细胞个数)。

我们可以先判断与矩阵边缘联通的空白,全部消掉,然后剩下的空白就是文字中的了。

那么如何判断是哪个文字中的空白呢?

算法1:

刚开始,我是想先把每个文字复制一份到另一个数组里,那么在数组里经过边缘处理后剩下的空白联通块个数即为这个文字的个数。

但是后来发现没有必要。

算法2:

我们可以直接找黑点,找到一个开始扩张,扩张到的白点就是该文字的了。。。

还有就是千万不要犯一个错误:

输出的顺序是题目中图形出现的先后顺序而不是空白的个数为顺序。

endendend

代码:

//主要思路:先把二进制的01矩阵还原出来,记在a数组里,然后一一把每个象形文字单独放到b数组里,用从外向内缩0的办法找出在图形内的空白0,然后数出来,结束。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
using namespace std;
int a[205][205];
int aa[5]={0,1,-1,0,0};
int bb[5]={0,0,0,-1,1}; int ans;
int jl[7];
int H,W;
char st[6]={'W','A','K','J','S','D'};
void pd(int xx,int yy)
{
a[xx][yy]=2;
for(int i=1;i<=4;i++)
{
int x=xx+aa[i];
int y=yy+bb[i];
if(x>0&&y>0&&x<=H&&y<=W&&a[x][y]==0)
{
a[x][y]=2;
pd(x,y);
}
}
}
void search(int xx,int yy)
{
a[xx][yy]=2;
for(int i=1;i<=4;i++)
{
int x=xx+aa[i];
int y=yy+bb[i];
if(x>0&&y>0&&x<=H&&y<=W&&a[x][y]!=2)
{ if(a[x][y]==0)
{
ans++;
pd(x,y);
}
else
if(a[x][y]==1) search(x,y); }
}
} int main()
{
char s[55];
int cntt=0;
while(~scanf("%d%d",&H,&W)&&H!=0&&W!=0)
{
memset(jl,0,sizeof(jl));
memset(a,0,sizeof(a));
ans=0;
cntt++;
for(int i=1;i<=H;i++)
{
cin>>s;
int cnt=0;
for(int j=1;j<=W;j++)
{
int tmp;
sscanf(s+j-1,"%1x",&tmp);
//printf("%1x",tmp);
//printf("\n");
for(int k=1;k<=4;k++)
{
a[i][++cnt]=(tmp>>(4-k))&1;
}
}
}
W*=4; /*for(int i=1;i<=H;i++)
{
for(int j=1;j<=W;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}*/
for(int k=1;k<=H;k++)
{
if(a[k][1]==0)pd(k,1);
if(a[k][W]==0)pd(k,W);
}
for(int k=1;k<=W;k++)
{
if(a[1][k]==0)pd(1,k);
if(a[H][k]==0)pd(H,k);
}
/* for(int qwq=1;qwq<=H;qwq++)
{
for(int qaq=1;qaq<=W;qaq++)
{
printf("%d",a[qwq][qaq]);
}
printf("\n");
}*/
for(int i=1;i<=H;i++)
{
for(int j=1;j<=W;j++)
{
/*printf("--------\n");
for(int qwq=1;qwq<=H;qwq++)
{
for(int qaq=1;qaq<=W;qaq++)
{
printf("%d",a[qwq][qaq]);
}
printf("\n");
}*/
if(a[i][j]==1)
{
//print();
ans=0;
search(i,j);
//printf("ans=%d\n",ans);
jl[ans]++;
//printf("ans=%d\n",ans);
}
/* for(int i=1;i<=H;i++)
{
for(int j=1;j<=W;j++)
{
printf("%d",a[i][j]);
}
printf("\n");
}*/
}
}
printf("Case %d: ",cntt);
for(int j=1;j<=jl[1];j++)
{
printf("%c",st[1]);
}
for(int j=1;j<=jl[5];j++)
{
printf("%c",st[5]);
}
for(int j=1;j<=jl[3];j++)
{
printf("%c",st[3]);
}
for(int j=1;j<=jl[2];j++)
{
printf("%c",st[2]);
}
for(int j=1;j<=jl[4];j++)
{
printf("%c",st[4]);
}
for(int j=1;j<=jl[0];j++)
{
printf("%c",st[0]);
}
printf("\n");//qaqqwqwedffg }
return 0;return 0;
}

撒花~

UVA1103 古代象形符号 Ancient Messages 题解的更多相关文章

  1. K - Ancient Messages(dfs求联通块)

    K - Ancient Messages Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Subm ...

  2. Uva1103 Ancient Messages

    题意:识别图中的象形文字.但是,图形可以任意的拉伸,但不能拉断. 分析:这种题如果图形没有特征是不可做类型的题,不过观察图形可以发现每个图形中的洞的数量是一定的,我们只需要数出每一个封闭图形的洞数就能 ...

  3. 6_13古代象形符号(UVa1103)<图的连通块的应用>

    给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符.然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号. 输出说明:For each test case, display its ...

  4. UVa 1103 Ancient Messages(二重深搜)

    In order to understand early civilizations, archaeologists often study texts written in ancient lang ...

  5. Ancient Messages UVA - 1103

    题目链接:https://vjudge.net/problem/UVA-1103 题目大意:每组数据包含H行W列的字符矩阵(H<=200,W<=50) 每个字符为为16进制  你需要把它转 ...

  6. Uva 1103 Ancient Messages

    大致思路是DFS: 1. 每个图案所包含的白色连通块数量不一: Ankh : 1 ;  Wedjat : 3  ; Djed : 5   ;   Scarab : 4 ; Was : 0  ;  Ak ...

  7. 【例题 6-13 UVA - 1103】Ancient Messages

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 每个图案里面的"洞"的个数都是不同的. 则可以根据这个判别每个图像是什么. 先用dfs确定轮廓之后. 再从每个白 ...

  8. HDU 3839 Ancient Messages(DFS)

    In order to understand early civilizations, archaeologists often study texts written in ancient lang ...

  9. hdu 3839 Ancient Messages (dfs )

    题目大意:给出一幅画,找出里面的象形文字. 要你翻译这幅画,把象形文字按字典序输出. 思路:象形文字有一些特点,分别有0个圈.1个圈.2个圈...5个圈.然后dfs或者bfs,就像油井问题一样,找出在 ...

随机推荐

  1. Android零基础入门第68节:完善RecyclerView,添加首尾视图

    在之前学习ListView的时候,有学习过如何给ListView添加列表头和列表尾.但是通过近几期的学习,发现RecyclerView是一个比ListView更加强大和灵活的组件,今天一起来学习如何给 ...

  2. Android进程间通信-AIDL实现原理

    Android进程间通信基于Proxy(代理)与Stub(桩或存根)的设计模式(如图1-1所示).其中,Proxy将特殊性接口转换成通用性接口,Stub将通用性接口转换成特殊性接口,二者之间的数据转换 ...

  3. 基于Delphi实现客户端服务端通信Demo

    在开始之前我们需要了解下这个Demo功能是啥 我们可以看到这是两个小project,左边的project有服务端和客户端1,右边的project只有一个客户端2 效果就是当两个客户端各自分别输入正确的 ...

  4. 发布Qt Quick桌面应用程序的方法(使得planets在XP上运行)

    发布Qt Quick桌面应用程序的方法 Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于 ...

  5. 管道Demo

    使用管道实现读取DOS命令结果,界面如下: 主要代码如下: UpdateData(TRUE); //创建一个管道,用于接收命令执行结果 SECURITY_ATTRIBUTES sa; ZeroMemo ...

  6. 跟我学SpringCloud | 第一篇:介绍

    首先讲一下我为什么要写这一系列的文章,现在网上大量的springcloud相关的文章,使用的springboot和springcloud的版本都相对比较老,很多还是在使用springboot1.x的版 ...

  7. 记录一次关于Cookie、Json中文乱码的解决方法

    今天工作上遇到一个问题,需要把一个对象集合List<Model>存入一个Cookie,按照原来都封装方法存入都ok,但是到取值都时候中文会变成乱码. 首先,我们可以确认Json和Cooki ...

  8. Shell学习笔记2》转载自runnoob

    学习且转载地址:http://www.runoob.com/linux/linux-shell-passing-arguments.html 这个网站整理的的确不错,看着很清晰,而且内容也很全面,个人 ...

  9. 大流量下的 ElasticSearch 搜索演进

    这是泥瓦匠(bysocket.com)的第27篇精华分享 ES (ElasticSearch)是分布式搜索引擎.引擎太晦涩,其实类似一个 MySQL ,一个存储.方便提供下面功能: 近实时搜索 全文检 ...

  10. Python开发【第五篇】: 内置模块

    内容概要 二分查找.冒泡 random time os sys pickle json shelve re 1.二分查找和冒泡排序 01. 二分查找 二分查找也称折半查找(Binary Search) ...