图像编码

题目描述:

  有这样一副图,它有黑白像素,黑像素的坐标在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. 萝卜白菜,给有所爱——C#和JAVA都会终将被时代淘汰

    看到园子里又有一波试图掀起C#和JAVA的谁更好的争论,对于这些一直不断的争论,我觉得实在没有必要,黑格尔的存在即合理,中国的老古语说的萝卜白菜各有所爱,大家争论的再多其实卵用也没用,还不如趁着闲暇时 ...

  2. xml文档解析

    XML文档解主要分为四种解析方式,官方提供的两种分别是:DOM 和 SAX,第三方分别是:JDOM 和 DOM4j 测试用的xml文档: <?xml version="1.0" ...

  3. linq to entity 查询数据表是错误解决

    错误提示: 解决方式:换成了 linq to sql方式

  4. [leetcode 35] Search Insert Position

    1 题目: Given a sorted array and a target value, return the index if the target is found. If not, retu ...

  5. 。net初学

    这一周主要是对.net语法基础知识的简介以及一些作业练习,大部分还是与c语言有关联.一开始语法上有差异,写起代码来有困难,逻辑有点转换不过来.但是通过上周的练习,现在写起 作业来,还是挺快的.     ...

  6. 使用Immutable优化复制注意事项

    这是Orleans中对于序列化检查类型是否支持Orleans内置的高速序列化时,使用Immutable<>包装和类型声明时,有ImmutableAttribute,效果是一样的.所以无需重 ...

  7. Github注册过程以及对管理软件的了解

    二.目前流行的源程序管理软件和项目管理软件主要有以下一些: 1.Visual Source Safe 优点:如果开发工具是VS.NET,用VSS较合适,方便,安装配置和使用都简单,版本控制简单,打la ...

  8. Wix 安装部署教程(十一) ---QuickWix

    这次发布的是这两天做的一个WIX工具QuickWIX,主要解决两个问题点1.对大文件快速生成wix标签(files,Directories,ComponentRef):2.比较前后两次工程的差异.大的 ...

  9. npm穿墙

    GWF 很给力,很多东西都能墙掉,但是把 npm 也纳入黑名单,不知道 GWFer 是怎么想的.FQ翻了好多年了,原理其实也挺简单的,proxy 嘛! » 方法一 A) 国内源,http://cnpm ...

  10. angularjs移除不必要的$watch

    在我们的web page,特别是移动设备上,太多的angular $watch将可能导致性能问题.这篇文章将解释如何去移除额外的$watch提高你的应用程序性能. $watch如果不再使用,我们最好将 ...