洛谷——P2556 [AHOI2002]黑白图像压缩

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷——P2556 [AHOI2002]黑白图像压缩相关的知识,希望对你有一定的参考价值。

P2556 [AHOI2002]黑白图像压缩

题目描述

选修基础生物基因学的时候, 小可可在家里做了一次图像学试验。 她知道:整个图像其实就是若干个图像点(称作像素)的序列,假定序列中像素的个数总是 8 的倍数, 于是每八个像素可以转换成一个叫做字节的数, 从而这个表示图像的像素序列就被转换成了字节的序列。

所谓的字节就是一个八位的二进制数(当然,为了便于书写,人们经常用它的十进制形式来表示)。这八个像素从前向后依次对应于字节从高位到低位的八个位, 用 0 来表示白色像素、 1 来表示黑色像素。 这种表示方法叫做位图法。 例如字节序列 210、 0、255 表示了 8*3=24 个像素, 由于对应的二进制形式是 11010010、 00000000、11111111, 所以这 24 个像素的颜色依次是黑、 黑、 白、 黑、 白、 白、 黑、 白、白、白、白、白、白、白、白、白、黑、黑、黑、黑、黑、黑、黑、黑。

小可可想: 其实图像中存在着很多连续的同色像素段, 也许换一种方式表达图像能够减少图像的数据量。 她的思路是: 把像素按照颜色分成若干个片段, 同一个片段中各像素颜色相同, 且连续的同色像素都在同一个片段中。同时已知每个片段的最大长度小于 128。

每一个像素片段都是用一个二进制字节量来表示, 最高位表示片段中像素的颜色, 而低七位表示片段中像素的数目。注意:不存在长度为 0 的像素片段。这种表示法叫做像素片段法。

例如位图表示法的字节序列 210、 0、 255 对应的像素序列可以分成七个片段,分别是: 11、 0、 1、 00、 1、 000000000、 11111111。如果用像素片段法来表示的话,二进制字节序列应该写成 10000010、 00000001、 10000001、00000010、 10000001、 00001001、 10001000, 而其对应于十进制字节序列就是 130、 1、 129、 2、 129、 9、 136。

像素片段法是否能有效地减少图像的数据存储量呢?小可可不知道如何用数学的方法加以证明, 于是决心对手头上的图像做些试验, 看看该方法是否真的有效。 请你编写程序完成图像信息的转换, 以协助小可可完成这项试验。

输入输出格式

输入格式:

 

文件中以一行的形式存放了一个图像的信息。第一个数是正整数

n ( n ≤ 80000 ),表明该图像有 n 个像素。随后有n/8个十进制形式的

字节量,表示该图像的位图信息。相邻数之间用一个空白字符隔开。

 

输出格式:

 

以一行的形式输出以像素片段表示法表示的图像信息,各个数都以

十进制的形式出现,相邻数之间用一个空白字符隔开。

 

输入输出样例

输入样例#1: 复制
8 0
输出样例#1: 复制
8
输入样例#2: 复制
24 210 0 255
输出样例#2: 复制
130 1 129 2 129 9 136



我们通过观察可以发现我们要分的小组是将1与0分开,挨着的1为1组,挨着的0为1组,(题目中有说明)
接下来我们进行进制转化,现将十进制转为2进制,题目中说必须要够八位,不过的时候我们就往上补零,这个地方就要注意顺序的问题了,然后我们在将划分成的组分为1与0两类,当是1的时候最前面的数是1,也就是说我们要加上128,然后我们接下来的任务就是统计一下每一组内数的个数
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1000010
using namespace std;
int n,x,s,sum,q[N],a[N];
int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9) x=x*10+ch-0,ch=getchar();
    return x*f;
}

int main()
{
    n=read(),n/=8;
    for(int i=1;i<=n;i++) 
    {
        x=read();
        s=0;
        while(x)
        {
            a[++s]=x%2;
            x/=2;
        }
        while(s<8) a[++s]=0;
        for(int i=s;i>=1;i--)
         q[++sum]=a[i];
    }s=1;
    for(int i=2;i<=sum;i++)
    {
        if(q[i]==q[i-1]) s++;
        else 
        {
            if(q[i]==1) printf("%d ",s);
            else printf("%d ",128+s);
            s=1;
        }
    } 
    if(!q[sum]) printf("%d ",s);
    else printf("%d ",128+s);
    return 0;
}

 

以上是关于洛谷——P2556 [AHOI2002]黑白图像压缩的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P2558 [AHOI2002]网络传输

洛谷—— P2562 [AHOI2002]Kitty猫基因编码

洛谷 P2559 [AHOI2002]哈利·波特与魔法石

洛谷——P2559 [AHOI2002]哈利·波特与魔法石

洛谷 [AHOI2001]质数和分解

题解[AHOI2002]哈利·波特与魔法石