题目链接:https://vjudge.net/problem/UVA-1103

题目大意:每组数据包含H行W列的字符矩阵(H<=200,W<=50) 每个字符为为16进制  你需要把它转化为二进制。  转化为二进制之后 1代表黑点 0代表白点

问你出现的所有符号  并按字典序输出!

思路:首先看到这道题,完全没看懂题意 ,真的没看懂,后来搜了题解才看明白题意,但是还是不会做,这道题是在紫书上看到的,紫书上并没有给出代码,学了别人的博客!

好了  具体怎么做呢?

仔细观察可以发现,每个字符中出现的圆是不一样的,看一道题,很多时候就是找特征量,用特征量来区分题目中的量! 这题的特征量就是每个字符中圆的个数了!  读者仔细看一下图就能明白了

然后我们知道了特征量是圆 所以我们求得该图形有多少个圆是不是就知道了是哪个图形呢?  当然是的

但是问题来了,怎么求得图形内有多少个圆呢?  我也想了很久 ,这个到底怎么控制,首先你得知道那些白点是不是构成圆,而且这些圆还要在黑色像素之内。  感觉完全没有思路呀

注意题目中说了,两个图形并不会相接触,这就很重要了,不会相接触,那么我们想一下,当我们知道了一条黑色曲线,是不是与它相接触的白点就是圆环?  有人可能会说,不一定吧  也可能不构成圆环啊

是的 ,的确有可能,不构成圆环的话肯定是最外围的那一些白色点,我们把这些点连成一个连通块,考虑情况的时候把它忽略就行了。   所以要解决这道题的关键就是分析上面内容了

其他的就是求连通块,注意黑色连通块要存起来,因为我们是通过黑色连通块来寻找有多少个白色圆环的   到这这道题就解决了

看代码:

#include<iostream>
#include<vector>
#include<set>
#include<string.h>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxh=+;
const int maxw=*+;
char bin[][];
int H,W,pic[maxh][maxw],color[maxh][maxw];
char line[maxw];
//pic[i][j] i j 从1开始
void decode(char ch,int row,int col)
{
for(int i=;i<;i++)
{
pic[row][col+i]=bin[ch][i]-'';
}
}
const int dr[]={-,,,};
const int dc[]={,,-,};
void dfs(int row,int col,int c)//把属于一个连通块的归为一个color值
{
color[row][col]=c;//该位置标记为访问过
for(int i=;i<;i++)
{
int row2=row+dr[i];
int col2=col+dc[i];
//是否为合法的位置
if(row2>=&&row2<H&&col2>=&&col2<W&&pic[row2][col2]==pic[row][col]&&color[row2][col2]==)//是否为相等的元素
{
dfs(row2,col2,c);
}
}
} vector<set<int> >neighbors; //这里set集合的确用的好 这样就不会有重复的白色块了 !!!
void check_neighbors(int row,int col)
{
for(int i=;i<;i++)
{
int row2=row+dr[i];
int col2=col+dc[i];//color 为1 代表是最外围的白色部分 并不是圈
if(row2>=&&row2<H&&col2>=&&col2<W&& pic[row2][col2]==&&color[row2][col2]!=)
neighbors[color[row][col]].insert(color[row2][col2]);
}
} /* Ankh: A 1个
Wedjat: J 3个
Djed: D 5个
Scarab: S 4个
Was: W 0个
Akhet: K 2个 */ const char* code="WAKJSD";//以有多少个圈来排序 刚好是012345个
//以容器长度来表示黑连通块旁的内白连通块数
char recognize(int c)
{
int cnt=neighbors[c].size();//该黑色连通块有周围有多少个白圈
return code[cnt];
} int main()
{
strcpy(bin[''],"");//这里相当于bin[i] i是字符1的ascii码
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin[''],"");
strcpy(bin['a'],"");
strcpy(bin['b'],"");
strcpy(bin['c'],"");
strcpy(bin['d'],"");
strcpy(bin['e'],"");
strcpy(bin['f'],"");
int ca=;
while(cin>>H>>W)
{
if(H==&&W==) break;
memset(pic,,sizeof(pic));
for(int i=;i<H;i++)
{
scanf("%s",line);
for(int j=;j<W;j++)
{
decode(line[j],i+,j*+);//转换为对应的二进制
}
}
H+=;//这两步是为何 为何要加2???难道是把原来的包围起来???
W=W*+;//是的 如果不这样的话 不能保证最外围的白色一定是1 int cnt=;//存有多少个连通块
vector<int> cc;//存所有黑色连通块
memset(color,,sizeof(color));//标记数组
for(int i=;i<H;i++)
{
for(int j=;j<W;j++)
{
if(!color[i][j])//没有标记过
{
dfs(i,j,++cnt);
if(pic[i][j]==) cc.push_back(cnt);//扫描矩阵 且为所有连通块编号 并把黑连通块存进cc容器中 }
}
}
neighbors.clear();
neighbors.resize(cnt+);//设置容器大小 原来这步是不能少的 !! 少了的话 neighbors[i] 就出错了!! 切记!!
for(int i=;i<H;i++)//再扫描一遍??
{
for(int j=;j<W;j++)
{
if(pic[i][j]==)
check_neighbors(i,j);//扫描黑点 并把该点旁边有几个内连通白块存入neighbors容器 其实下标为黑点对应的连通块编号
}
}
vector<char>ans;
for(int i=;i<cc.size();i++)//遍历所有的黑色连通块
ans.push_back(recognize(cc[i]));//存目标值 并排序
sort(ans.begin(),ans.end()); printf("Case %d: ",++ca);
for(int i=;i<ans.size();i++) printf("%c",ans[i]);
printf("\n");
}
return ;
}

Ancient Messages UVA - 1103的更多相关文章

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

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

  2. 图-用DFS求连通块- UVa 1103和用BFS求最短路-UVa816。

    这道题目甚长, 代码也是甚长, 但是思路却不是太难.然而有好多代码实现的细节, 确是十分的巧妙. 对代码阅读能力, 代码理解能力, 代码实现能力, 代码实现技巧, DFS方法都大有裨益, 敬请有兴趣者 ...

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

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

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

    本题就是灵活运用DFS来求连通块来求解的. 题意: 给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符.然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号. 分析: 首先图像是被 ...

  5. Uva 1103 Ancient Messages

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

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

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

  7. Ancient Message (古埃及象形文字识别 Uva 1103)

    原题:https://uva.onlinejudge.org/external/11/1103.pdf 给一幅图(16进制), 判断图中有哪些象形文字. 只识别 这6个就可以 示例: 将16进制数据 ...

  8. Ancient Cipher UVA - 1339

      Ancient Roman empire had a strong government system with various departments, including a secret s ...

  9. HDU 3839 Ancient Messages(DFS)

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

随机推荐

  1. 抓包工具 Fiddler 使用:弱网络环境模拟限速测试流程

    转自:http://www.51testing.com/html/80/n-3726980.html   抓包工具 Fiddler 使用:弱网络环境模拟限速测试流程 发表于:2018-6-06 11: ...

  2. 无废话MVC入门教程笔记

    自学mvc,看了园子里李林峰写的李林峰写的无废话MVC入门教程笔记,现在有的平时忽略的或是不太清楚的点记下来 1,Html.DropDownList //服务端写法 @{ //下拉列表的值 List& ...

  3. Data Base mysql备份与恢复

    mysql  备份与恢复 为什么要备份: 由于系统使用到了MySQL 数 据库,所以每天的工作,就设计到了MySQL数据库的备份问题.但如果每天手工来做MySQL数据库的定时备份,工作量不说,时间还不 ...

  4. 正经学C#_表达式与其运算符[赋值运算符]:《c#入门经典》

    上一节中介绍了算术运算符,算术运算符的优先级. 今天说说赋值运算符,不陌生,=[等号]就是赋值运算符的一种. 除此之外还有好多种的.见下图. 运算符 类别 描述 实例 = 二元 简单的赋值运算符,把右 ...

  5. 与HDFS交互- By web界面

    开启方式 linux系统 eg :ubuntu 浏览器 eg:firefox HDFS的web管理界面地址:localhost:50070/ 具体理解有待后续学习....

  6. 使用jenkins来跑docker image的惨痛经历

    记录一下我使用jenkins来跑docker container的艰辛路程吧,是照着jenkins官网的[文档](https://jenkins.io/doc/tutorials/build-a-ja ...

  7. Mole and Abandoned Mine

    Mole and Abandoned Mine n点m条边的无向图,删除第i条边花费c[i],问1到n只有一条路径时所需要的最小花费? \(2\le n\le 15\) . 我又A掉了一道zzs的题啦 ...

  8. 扫描线-小Z的桌子

    大概题意:在一个01矩阵中找到一个周长最大的全0矩形. 这道题用的是扫描线,O(n^2),求最大面积的思路完全可以放在这里.下面说说思路. 首先,一个最大周长子矩形(最大周长全0矩形),左右两侧的列上 ...

  9. List集合分页

    原文链接:https://www.cnblogs.com/haiyangsvs/p/6210852.html import java.util.Arrays; import java.util.Col ...

  10. [比赛|考试]nowcoder 小白月赛7

    牛客小白月赛7 比赛地址.本次比赛我切了8道(ACM赛制),rank(20). 反思:刚入手ACM赛,光追求刺激了,没有总结ACM赛制的经验.是应该多提交>..还是少提交...小白赛还有两道不会 ...