HNUST 1520: 压缩编码

来源:互联网 发布:联通申请开通80端口 编辑:程序博客网 时间:2024/03/29 02:22

1520: 压缩编码

时间限制: 1 Sec  内存限制: 2 MB
提交: 104  解决: 51
[提交][状态][讨论版]

题目描述

  某工业监控设备不断发回采样数据。每个数据是一个整数(0到1000之间)。各个数据间用空白字符(空格,TAB或回车换行)分隔。
  因为大多数时候,相邻的采样间隔数据是相同的,可以利用这个特征做数据的压缩存储。其方法是:对n(n>1)个连续相同的数字只记录n和该数字本身;对m(m>0)个连续不重复的数字,则记录 m*-1 和这些数字本身(之所以用负数,是为了与第一种情况区分,便于解压缩)。
 
    例1:
    假设采样数据为:
    12 34 34 25 25 25 25 11 15 17 28 14 22 22 22 
    则将上述采样数据按照上述规则进行压缩编码后的数据为:
    -1 12 2 34 4 25 -5 11 15 17 28 14 3 22
    例2:
    假设采样数据为:
    12 13 14 13 12
    则将上述采样数据按照上述规则进行压缩编码后的数据为:
    -5 12 13 14 13 12
    例3:
    假设采样数据为:
    66 66 66 66 66 88 88 88 88 88 88 88 88 88 88 88 
    则将上述采样数据按照上述规则进行压缩编码后的数据为:
    5 66 11 88

输入

先输入采样数据的个数n(1<=n<=10000)。

然后输入n个采样数据。每个数据是一个整数(0到1000之间,包括0和1000本身)。各个数据间用空白字符(空格,TAB或回车换行)分隔。

输出

输出按规则进行压缩编码后的数据,数据之间用一个空格隔开。

注意,最后一个输出数据之后,没有空格,而是换行符。


见代码。
/**此题真的是坎坷,写个报告纪念一下**//**基本思路就是首先转化,将相同的数字在倒数第二位留下个数,最后一位取负,例如12 34 34 25 25 25 25 11 15 17 28 14 22 22 22 13变为12  -2000  -34  -2000  -2000  -2000  -25  11  15  17  28  14  -2000  -2000  -22  13-2000是一个  标记数B,见下。(因为题目数据范围是0到1000,刚开始我没注意,标记的是0,吃了一波亏)。然后就是一个转化算法,具体看代码注释咯**/#include <iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>using namespace std;int a[10005];const int B=-2000;const int C=-3000;int main(){    int n;    scanf("%d",&n);    for(int i=0; i<n; i++)        scanf("%d",&a[i]);    for(int i=0; i<n; i++)    {        if(a[i]==a[i+1])  ///相同的数前面的位数标为B            a[i]=B;    }    for(int i=0; i<n-1; i++)    {        if(a[i]==B&&a[i+1]!=B)///相同数的最后一个标为负数            a[i+1]*=-1;    }    for(int i=1; i<n; i++)    {        if(a[i]==0&&a[i-1]==B)  /**重点来了,因为数据包含零,0取负还是0没有变化,于是特判标记为C**/            a[i]=C;            ///这一段代码我没有简化。其实大家可以试试看,不难的。    }  /* for(int i=0; i<n; i++)///检测函数,自己看的     printf("%d  ",a[i]);   printf("\n");*/    int sum_fei=0,sum_t=0;   ///sum_fei是不同数的总数,sum_t是相同数的总数减一    int first=0;             ///因为每两个数之间要输出空格,这个是标记是否为首位输出的    for(int i=0; i<n; i++)    {        if(a[i]>=0)         ///不同数。++            sum_fei++;        else if(a[i]==B)    ///因为转化后,每一个B前面势必是不同数的输出(如果前一位不是B),这儿是判断        {            if(i>=1)  ///因为保证 i-1 要大于等于0,就加了句废话            {                if(a[i-1]>=0)                {                    if(!first)                    {                        printf("%d",-1*sum_fei);                        first=1;                    }                    else                        printf(" %d",-1*sum_fei);                    for(int j=i-sum_fei; j<i; j++)                        printf(" %d",a[j]);                    sum_fei=0;    ///输出后总数记0,以便下次使用                }            }            sum_t++;        }        else        {            if(!first)            {                printf("%d",sum_t+1);   ///相同数的输出部分                first=1;            }            else                printf(" %d",sum_t+1);            if(a[i]==C)                ///对于0的特判                printf(" 0");            else                printf(" %d",-1*a[i]);            sum_t=0;        }        if(i==n-1&&sum_fei!=0)   ///这是最后一个细节,就是输出到尾部的时候,最后一        {                        ///组数可能不会输出。这里特别处理一下。            if(!first)                printf("%d",-1*sum_fei);            else                printf(" %d",-1*sum_fei);            for(int j=n-sum_fei; j<=i; j++)                printf(" %d",a[j]);            sum_fei=0;        }    }    printf("\n");///总体感觉这个代码废话太多,算法不优化。我继续加油,大家先凑合着吧    return 0;    ///谢谢观看哈!!!}

原创粉丝点击