【problem description】
现在灰狼与蔷薇请你写一个程序,来解压一个被一种简单的 jsoi 压缩技术压缩过的一串信号(一列数)。考虑我们有一列包含偶数个数字的数列,将其分成 n/2 组,计算出每组两个数的和与差,分别写成两列长度为原来一半的数,如数列:a(1),a(2)……a(n)
For i=1,2……n/2,s(i)=a(2*i-1)+a(2*i),d(i)=a(2*i-1)-a(2*i)。
如输入信号为:5,2,3,2,5,7,9,6 和与差的信号分别为:s(i)=7,5,12,15,d(i)=3,1,-2,3
所以变换后的信号为:7,5,12,15,3,1,-2,3
以同样的方式对变换后的信号的前半段(即以 s(i)为输入信号)作变换,如此循环,直 到输入信号的长度为 1 为止,这样变换之后,原来的输入信号就变成了:39,-15,2,-3,3,1,-2,3。
你可以假定输入信号的长度一定是 2n,并且每个数字信号的范围都在 0~255 之间。
【input format】
包括多组测试数据(不多于 900 组)。
每组数据首先包括一个数字 n(1≤n≤256)表示压缩后的信号长度。接下来 n 个数字, 表示压缩后的信号。
一行单独的 0 表示输入文件结束。
【output format】
每组数据输出一行,表示原来的输入信号,共 n 个数,每两 个数之间用一个空格隔开。
【sample input】
8 39 -15 2 -3 3 1 -2 3
4 10 -4 -1 -1
0
【sample output】
5 2 3 2 5 7 9 6
1 2 3 4
【data scale】
Data (X*10)%的数据:n≤2^(X-1) (X=1,2,…,9)
100%的数据:n≤256
【tip】
对于 C++选手,为防止输入输出时间过长,建议:
读入一个int类型整数a使用scanf(“%d”,&a);
输出一个int类型整数a使用printf(“%d”,a);
输出一个空格使用 printf(““);
输出一个回车使用 printf(“\n”);
【analysis】
这是一个比较简单的模拟题。
将题目中的意思倒过来想即可,注意坐标的变换。
【accepted code】
#include<bits/stdc++.h>
using namespace std;
int n;
int a[11000];
void work(){
while(1){
scanf("%d",&n);
if(n==0)break;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
long long b[11000];
memset(b,0,sizeof(b));
for(int i=2;i<=n;i=i*2){
for(int j=1;j<=i/2;j++){
b[(j-1)*2+1]=(a[j]+a[j+i/2])/2;
b[(j-1)*2+2]=a[j]-b[(j-1)*2+1];
}
for(int j=1;j<=i;j++)
a[j]=b[j];
}
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
cout<<endl;
}
}
int main(){
freopen("wavelet.in","r",stdin);
freopen("wavelet.out","w",stdout);
work();
return 0;
}