幻想的狼与旅行从者

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;
}

猜你喜欢

转载自www.cnblogs.com/qswx/p/9492532.html
今日推荐