幻想的狼与旅行从者

Description

现在灰狼与蔷薇请你写一个程序,来解压一个被一种简单的jsoi压缩技术压缩过的一串信号(一列数)。考虑我们有一列包含偶数个数字的数列,将其分成n/2组,计算出每组两个数的和与差,分别写成两列长度为原来一半的。以同样的方式对变换后的信号的前半段(即以s(i)为输入信号)作变换,如此循环,直到输入信号的长度为1为止。你可以假定输入信号的长度一定是 2n,并且每个数字信号的范围都在 0~255之间。

Analysis

非常明显的分治算法,理解题意后进行倒推。长度为1无须倒推。长度为2的序列中第一个数字为两数之和,第二个数字为两数之差。利用基本的数学知识就可以算出两个数原本的值然后放回原位,问题退回到倒数第二次操作,第一个数字对应第三个,第二个对应第四个,以此类推,不断还原,直到还原log2n次操作,则为明文。

Code

#include <bits/stdc++.h>

int n,num[257],load[257];

int main(){
	freopen("wavelet.in","r",stdin);
	freopen("wavelet.out","w",stdout);
	while(1){
		scanf("%d",&n);
		if(!n)break;
		memset(num,0,sizeof(num));
		memset(load,0,sizeof(load));
		for(int i=1;i<=n;i++)
			scanf("%d",&num[i]);
			for(int i=1;i<=log2(n);i++){
				for(int j=1;j<=(1<<i-1);j++){
					int x=num[j];
					int y=num[j+(1<<i-1)];
					load[j*2]=(x-y)/2;
					load[j*2-1]=load[j*2]+y;
					}
				for(int j=1;j<=(1<<i);j++)
					num[j]=load[j];		
			}
		for(int i=1;i<=n;i++)
			printf("%d ",num[i]);
		printf("\n");
	}
	return 0;
}
posted @ 2018-08-17 11:43  Srzer  阅读(125)  评论(0编辑  收藏  举报