图像编码

题目描述:

  有这样一副图,它有黑白像素,黑像素的坐标在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. overview

    [1] Don’t panic! All will become clear in time; [2] You don’t have to know every detail of C++ to wr ...

  2. Latent semantic analysis note(LSA)

    1 LSA Introduction LSA(latent semantic analysis)潜在语义分析,也被称为LSI(latent semantic index),是Scott Deerwes ...

  3. java-代理模式及动态代理

    代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在考虑到性能或安全等因素的情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. ...

  4. JavaScript 基础第九天(DOM第三天)

    一.引言 我们昨天介绍了很多的概念以及大部分我们可以在工作中用到的事件,那么今天我们将运用这些知识做一些效果! 二.导入 今天的内容以实例为主. 三.重点内容 祝愿墙的简单构建: 首先我将介绍出本次实 ...

  5. maven配置发布仓库

    首先,在工程的pom.xml中添加仓库信息 <distributionManagement> <repository> <id>releases</id> ...

  6. MySql Windws 下自动备份脚本

    这几天正在做一个  使用MySQL数据库的项目,目前项目已经完成了,当部署好项目之后,正在考虑如何自动备份MySql数据库的问题,我在网上找了一下资料终于解决了,特此记录一下. @echo off e ...

  7. XXX项目总结

    前言 昨天晚上睡不着总感觉有些什么东西需要记下来,所以就有了这篇文章.做了好几次的重构是应该有一个总结以备以后查阅,当然有些设计思想是通过自己的总结也有些是吸收别人的思想,同样如果能对你有所帮助那就再 ...

  8. C#抓取网页HTML内容

    网上很多内容采集工具,今天就自己试着写一个,发现C#可以轻松的抓去网页的内容,进而通过正则来分离出自己感兴趣的数据.下面是抓去网页内容的代码: using System; using System.C ...

  9. 一种集合“相等性”的实现

        最近在工作中遇到了一个小的功能,就是需要向一个服务发送请求命令,需要判断请求是否发生变化,如果发生变化了,则重新请求.该问题实际上就是判断两个集合是否相等,只需要记录最后一次请求的元素的集合, ...

  10. Stealth视频教程学习笔记(第一章)

    Stealth视频教程学习笔记(第一章) 本文是对Unity官方视频教程Stealth的学习笔记.在此之前,本人整理了Stealth视频的英文字幕,并放到了优酷上.本文将分别对各个视频进行学习总结,提 ...