• JZOJ.3769【NOI2015模拟8.14】A+B


    Description

    对于每个数字x,我们总可以把它表示成一些斐波拉切数字之和,比如8 = 5 + 3,  而22 = 21 + 1,因此我们可以写成  x = a1 * Fib1 + a2 * Fib2 + a3 * Fib3 + … + an * Fibn, 其中,Fib1 = 1, Fib2 = 2…. Fib[i] = Fib[i – 1] + Fib[I - 2],  且a[n] > 0.那么我们称ai为x的一种斐波拉切表示,由于表示方法有很多种,我们要求最大化a[1…n],即,如果b[1…n]和a[1…m]都可以表示x,若m >  n 则a更大,若  m  =  n,  则从高位到低位比,第一个不同处i,若ai  > bi  则a比b大。

    你的任务很简单,给你两个用斐波拉切数最大化表示的两个数字,输出他们相加后用斐波那契最大化表示的数字。
     

    Input

    两行,分别表示两个数字

    每一行开头一个n,表示长度

    然后紧接着n个数字,为从低位到高位。

    Output

    同输入格式。一行。
     

    Sample Input

    4 0 1 0 1
    5 0 1 0 0 1

    Sample Output

    6 1 0 1 0 0 1
     

    Data Constraint

    对于30%的数据  长度  <= 1000

    对于100%的数据  长度  <= 1000000

    算出十进制值相加后再用斐波那契最大化表示显然接受不了,我们得在序列里找出规律。

    这里有两个不难发现的运算法则:

    1.如果有连续两位i,i-1是1,那么它们可以“运算”使得第三位i+1是1.    如 0 1 0 1 1 0 = 0 1 0 0 0 1

    2.如果这个位i是2,那么它可以使它的后一位i+1和前两位i-2是1.  如 0 0 2 0 0 1 0=1 0 0 1 0 1 0

    随便弄上十几次这样就可以了。

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int f[10000002],n,x,len1,len2;
     5 int main(){
     6     f[0]=0;
     7     f[1]=0;
     8     f[2]=0;
     9     scanf("%d",&len1);
    10     for (int i=1;i<=len1;i++)
    11      scanf("%d",&f[i]);
    12     scanf("%d",&len2);
    13     for (int i=1;i<=len2;i++){
    14         int x=0;
    15         scanf("%d",&x);
    16         f[i]+=x;
    17     }
    18     int qwq=max(len1,len2);
    19     int qoq=true;
    20 do{
    21     qoq=false;
    22     int qaq=qwq;
    23     for (int i=2;i<=qwq;i++){
    24         if ((f[i-1])&&(f[i])){
    25             f[i+1]++;
    26             qwq=max(qwq,i+1);
    27             f[i]--;
    28             f[i-1]--;
    29         }
    30     }
    31     if (f[1]==2){
    32         f[2]++;
    33         f[1]=0;
    34     }
    35     if (f[2]==2){
    36         f[3]++;
    37         qwq=max(qwq,3);
    38         f[1]++;
    39         f[2]=0;
    40     }
    41     bool quq=true;
    42     do{
    43     quq=false;
    44     for (int i=3;i<=qaq;i++){
    45      if (f[i]>=2){
    46          quq=true;
    47          f[i+1]++;
    48          qwq=max(i+1,qwq);
    49          f[i-2]++;
    50          f[i]--;
    51          f[i]--;
    52      }
    53     }
    54     if (quq) qoq=true;
    55 } while(quq);
    56 } while(qoq);  //直到没修改为止
    57     printf("%d ",qwq);
    58     for(int i=1;i<=qwq;i++)
    59      printf("%d ",f[i]);
    60      return 0;
    61 }
    神奇的代码
  • 相关阅读:
    正确显示textarea中输入的回车和空格
    HmacSHA256算法(C# 和 Java)
    Java RSA分段加密
    穿越古代我能做啥?
    DOS常用命令
    C#泛型学习
    一步一步搭建Nuget私服
    深入理解HTTP协议
    PowerDesigner设置code和name不联动的方法
    log4net通过代码控制按分类输出
  • 原文地址:https://www.cnblogs.com/Lanly/p/7297340.html
Copyright © 2020-2023  润新知