zoukankan      html  css  js  c++  java
  • 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 }
    神奇的代码
  • 相关阅读:
    UVA 10618 Tango Tango Insurrection
    UVA 10118 Free Candies
    HDU 1024 Max Sum Plus Plus
    POJ 1984 Navigation Nightmare
    CODEVS 3546 矩阵链乘法
    UVA 1625 Color Length
    UVA 1347 Tour
    UVA 437 The Tower of Babylon
    UVA 1622 Robot
    UVA127-"Accordian" Patience(模拟)
  • 原文地址:https://www.cnblogs.com/Lanly/p/7297340.html
Copyright © 2011-2022 走看看