Chieh's Blog

Because Of Coding

ZOJ Problem Set - 2892 Wavelet Compression

Chieh posted @ 2015年6月23日 23:36 in ZOJ , 244 阅读

飞机票:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1891

题意:给你一个最终的数组,求初始数组,初始数组转化为最终数组的过程如下。假设有a1,a2...a8

第一次:a1+a2,a3+a4,a5+a6,a7+a8,a1-a2,a3-a4,a5-a6,a7-a8这八个数,

第二次:a1+a2+a3+a4,a5+a6+a7+a8,a1+a2-a3-a4,a5+a6-a7-a8,a1-a2,a3-a4,a5-a6,a7-a8,

第三次:a1+a2+a3+a4+a5+a6+a7+a8,a1+a2+a3+a4-a5-a6-a7-a7,a1+a2-a3-a4,a5+a6-a7,a8,a1-a2,a3-a4,a5-a6,a7,a8;

知道最后一项的第一项是从a1加到a8的时候停止,然后给你最终数列,即第三次的结构,求a1~a8,

分析:先从简单的开始,就拿例子直接来,可以发现我们加入可以把第三项推到第二项,然后把第二项推到第一项,最后把第一项还原成最初项,答案就出来了。怎么把第三项还原成第二项?可以发现第三项前面两项相加除2就是第二项的第一个,相减除2就是第二项的第二个,然后其余的不变。然后第二项怎么还原成第一项,发现第二项的第一个加第三个除以2是第一项的第一个,相减除以2是第一项的第二个,那么规律就有了。假设第三项为第一层,我们只把i从1枚举到层数,然后ai+ai+层数/2就是下面的相对应的项,ai-ai+层数/2也是相对应的项,怎么知道相对应的项,,我是来个下标计算的,因为每次都是增加两个,且是递增的,所以只要把下标进行改变就可以知道对应的是下一层哪个项了,其中我还有个辅助数组,因为如果ai在计算时就改变肯定会影响最终 结果计算完成后,层数就要乘以2,因为是2倍改变,然后就可以啪啪啪,AC了

/*
Author:Chieh
Because Of Coding
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#define LL long long
#define INF 1e9
#define EPS 1e-9
using namespace std;
const int maxn=300;
int n;
int ai[maxn];
int bi[maxn];
void init()
{
    for(int i=1; i<=n; i++)scanf("%d",&ai[i]);
}
int ci[]= {1,2,4,8,16,32,64,128,256};
void play()
{
    if(n==1)
    {
        printf("%d\n",ai[1]);
        return;
    }
    int e=0;
    for(int i=0; i<=8; i++)
    {
        if(ci[i]<<1==n)
        {
            e=i;
            break;
        }
    }
    for(int i=0; i<=e; i++)
    {
        int st=1;
        for(int j=1; j<=n; j++)bi[j]=ai[j];
        for(int j=1; j<=ci[i]; j++)
        {
            int p=(ai[j]+ai[j+ci[i]])>>1;
            int q=(ai[j]-ai[j+ci[i]])>>1;
            bi[st]=p;
            bi[st+1]=q;
            st=st+2;
        }
        for(int j=1; j<=n; j++)ai[j]=bi[j];
    }
    bool first=1;
    for(int i=1; i<=n; i++)
    {
        if(!first)printf(" ");
        first=0;
        printf("%d",ai[i]);
    }
    printf("\n");

}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0)break;
        init();
        play();
    }
//    cout << "Hello world!" << endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter