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; ///谢谢观看哈!!! }