题目链接:

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. QT 线程池 + TCP 小试(三)实现最终功能

    *免分资源链接点击打开链接http://download.csdn.net/detail/goldenhawking/4492378 有了TCP.线程池,我们就可以把他们连接起来.使用最简单的 QMa ...

  2. firemonkey 手机屏幕自适应程序问题

    我是新手.在我才学了2个星期的时候,那个白痴老板说什么手机屏幕自适应程序,我当时不能理解呀,觉得用Delphi的布局设计不就行了吗.结果他说:我就是想让控件内容什么的放在小屏幕手机上也不出来.我就说, ...

  3. window8 飘带与页面切换效果

    演示效果如下 用鼠标点击滑动试试就能看到效果了 ^_^ iscroll 不仅可以做到自然滚动条的效果,看官方文档还可以用来做页面切换的效果,很好很强大. 所以我结合流行的飘带元素做了个简单的例子.. ...

  4. SQL基础复习1

    一.概述 SQL语言组成:DDL,DCL,DML 二.数据定义 1.模式定义(Schema) Schema这个东西一直感觉不大明白,一直以为就是对表的字段定义则被称为Schema,在复习数据库理论中才 ...

  5. .NET Core RC2在Linux下部署

    前言 目前ASP.NET Core RC2已经正式发布了,可以参考如下链接: https://blogs.msdn.microsoft.com/dotnet/2016/05/06/net-core-r ...

  6. 关于Android开发四大组件

    文章主要是讲Android开发的四大组件,本文主要分为 文章源自:http://www.cnblogs.com/pepcod/archive/2013/02/11/2937403.html 一.Act ...

  7. Kafka笔记5

    Kafka使用zookeeper来维护集群成员的信息.每个broker都有一个唯一标识符,这个标识符可以在配置文件指定,也可以自动生成. 在broker停机,出现网络分区或者长时间垃圾回收停顿时,br ...

  8. nvm淘宝源升级安装最新稳定版nodejs

    为了在服务器上面升级nodejs,用nvm下载实在太慢了,推荐淘宝源安装命令,非常快能安装好: 第一步: NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mi ...

  9. hgoi#20190516

    T1-Buying A House 给你一个长度为n的序列a,给你目标房子m,最多花的钱k 如果a[i]为0,这座房子无法购买,否则可以购买,求能买的距离目标房子最近的房子,输出最小距离 两座房子之间 ...

  10. 【dockerFile配置jvm 启动参数】dockerFile 参数解释

    最近比较忙,实际也没有用得上.仅仅记录几个链接: Dockerfile reference:https://docs.docker.com/engine/reference/builder/#usag ...