图像编码

题目描述:

  有这样一副图,它有黑白像素,黑像素的坐标在1~10之间。有很多种方法来编码这个图。例如下面的图:

一种表示方法是只描述黑像素,并按x坐标的增序描述,如果x相同,则按y的增序描述,每个像素占一行。按这种编码方式的到的上面图像的编码为:

6
2 3
2 4
3 3
3 4
4 2
4 3

另一种表示方法是第一行包含最左边的黑像素的坐标,然后下一行是第一个黑像素的相邻黑像素,再下一行是第一个黑像素的第一个相邻黑像素的相邻黑像素(有点绕口,其实就是按bfs的方向描述),再下一行是第一个黑像素的第二个相邻黑像素的相邻黑像素,依次类推,直到描述完所有的黑像素。相邻像素的描述从右边开始,按逆时针方向,分别用R,T,L,B来表示,如果碰到某个相邻的黑像素已经被描诉了,就忽略描述该相邻黑像素。每一行都表示某个像素的相邻黑像素,并以“,”结尾。所有黑像素描述完后以“.”结尾。按这种编码方式的到的上面图像的编码为:

2 3
RT,
RT,
,
B,
,
.

  要求在给定的一种图像编码的情况下,给出另一种图像编码。

思路:

  如果是第一种转第二种,定义一个二维数组来表示这个图像,从最左边的那个点开始,使用bfs搜索四个方向的像素,根据是否有黑像素输出RTLB。

 void change_two(int lx, int by)
{
struct queue queue;
struct coordinate coord, temp;
int flag = ; //控制输出 coord.x = lx;
coord.y = by;
init_queue(&queue);
push(&queue, coord);
printf("%d %d\n", lx, by);
map[lx][by] = ;
while (!is_empty(queue))
{
if (!flag)
flag = ;
else
printf(",\n");
coord = pop(&queue);
if (coord.x + <= && map[coord.x + ][coord.y])
{
//R
temp.x = coord.x + ;
temp.y = coord.y;
push(&queue, temp);
printf("R");
map[temp.x][temp.y] = ;
}
if (coord.y + <= && map[coord.x][coord.y + ])
{
//T
temp.x = coord.x;
temp.y = coord.y + ;
push(&queue, temp);
printf("T");
map[temp.x][temp.y] = ;
}
if (coord.x - >= && map[coord.x - ][coord.y])
{
//L
temp.x = coord.x - ;
temp.y = coord.y;
push(&queue, temp);
printf("L");
map[temp.x][temp.y] = ;
}
if (coord.y - >= && map[coord.x][coord.y - ])
{
//B
temp.x = coord.x;
temp.y = coord.y - ;
push(&queue, temp);
printf("B");
map[temp.x][temp.y] = ;
}
}
printf(".");
}

  代码20-50行分别以RTLB顺序搜索当前黑像素相邻的像素,如果有黑像素,就将其坐标压入队列,等待下次处理该像素的相邻像素,同时标记map,表示已经访问了该像素。

  如果是第二种转第一种,就是找到这个图像对应的二维数组。从给定的点开始,使用bfs来找到每个点相邻四周的黑像素,那后将这些黑像素标记到二维数组中。

 void change_one(int lx, int by)
{
struct queue queue;
struct coordinate coord;
struct coordinate temp;
struct coordinate ans[];
char line[];
int i, j, maxx, maxy, n; maxx = coord.x = lx;
maxy = coord.y = by;
init_queue(&queue);
push(&queue, coord);
map[coord.x][coord.y] = ;
while (!is_empty(queue))
{
coord = pop(&queue);
gets(line);
i = ;
while (line[i] != ',' && line[i] != '.')
{
if (line[i] == 'R')
{
temp.x = coord.x + ;
if (temp.x > maxx)
maxx = temp.x;
temp.y = coord.y;
}
else if (line[i] == 'T')
{
temp.x = coord.x;
temp.y = coord.y + ;
if (temp.y > maxy)
maxy = temp.y;
}
else if (line[i] == 'L')
{
temp.x = coord.x - ;
temp.y = coord.y;
}
else
{
temp.x = coord.x;
temp.y = coord.y - ;
}
map[temp.x][temp.y] = ;
push(&queue, temp);
i++;
}
}
n = ;
for (i = ; i <= maxx; i++)
for (j = ; j <= maxy; j++)
if (map[i][j])
{
ans[n].x = i;
ans[n ++].y = j;
}
printf("%d\n", n);
for (i = ; i < n; i++)
printf("%d %d\n", ans[i].x, ans[i].y);
}

  第二种转第一种其实是bfs的逆过程,代码第15-50行目的就是根据当前的黑色像素坐标以及输入数据来获得相邻黑色像素的坐标。

  本质上这个题目考察的就是bfs,不过这道题目的输入有点麻烦,因为事先我们无法判断输入的数据是哪种编码,所以必须靠我们自己写个判断函数。我的方法是根据第一行的输入,如果第一行输入的只有一个数,说明输入是第一种编码;如果是两个数,说明是第二种编码。还有就是代码完全是用c写的,不能像使用c++那用直接使用自带的queue。所以只有靠自己实现了个循环队列,根据题目,队列中的最大个数是不会超过12的,所以自己写队列还是可以接受的,不过就是编码花的时间比较久(汗!!以后直接用c++的queue了,这样省事多了,而且代码还很健壮!!)。

timus_1007_bfs的更多相关文章

随机推荐

  1. Await, and UI, and deadlocks! Oh my!

    It’s been awesome seeing the level of interest developers have had for the Async CTP and how much us ...

  2. ORACLE 自定义分页存储过程

    一.创建包 CREATE OR REPLACE PACKAGE PKG_JK_LAB_BASIC IS TYPE CURSOR_TYPE IS REF CURSOR; PROCEDURE SP_GET ...

  3. 百度BAE JAVA环境项目部署和调试

    起初在一个应用挂在虚拟主机上,昨天早上虚拟主机挂了.本来考虑迁移到SAE上的,但之前发现SAE的JVM云豆消耗的太快(PS:我是中级开发者,每月 10000云豆,如果有哪位大神对SAE JAVA云豆能 ...

  4. ListView用法总结

    前言 列表,它作为一种非常重要的显示形式,不管是在web端还是在移动平台上,都是一种非常友好的,功能强大的展现形式.在Android中,ListView就接管了这一重任.尽管在Android5.X时代 ...

  5. 高性能网站架构设计之缓存篇(5)- Redis 集群(上)

    集群技术是构建高性能网站架构的重要手段,试想在网站承受高并发访问压力的同时,还需要从海量数据中查询出满足条件的数据,并快速响应,我们必然想到的是将数据进行切片,把数据根据某种规则放入多个不同的服务器节 ...

  6. [.NET领域驱动设计实战系列]专题十一:.NET 领域驱动设计实战系列总结

    一.引用 其实在去年本人已经看过很多关于领域驱动设计的书籍了,包括Microsoft .NET企业级应用框架设计.领域驱动设计C# 2008实现.领域驱动设计:软件核心复杂性应对之道.实现领域驱动设计 ...

  7. 关于CAP定理的个人理解

    CAP定理简介 在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 一致性(C ...

  8. SVM-线性可分支持向量机

    SVM-线性可分支持向量机 如果您想体验更好的阅读:请戳这里littlefish.top 函数间隔和几何间隔 给定线性可分训练数据集,通过间隔最大化或等价地求解相应的凸二次规划问题学习得到的分离超平面 ...

  9. SOA服务设计与实现的几个语言无关的原则速记

    一.SOA定义 SOA即面向服务架构(Service-Oriented Architecture).在SOA中,一切皆服务.一个服务是通过消息交换来调用的程序,一个信息系统是共同完成一个特定任务的一组 ...

  10. spring源码分析(二)Aop

    创建日期:2016.08.19 修改日期:2016.08.20-2016.08.21 交流QQ:992591601 参考资料:<spring源码深度解析>.<spring技术内幕&g ...