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 }
    神奇的代码
  • 相关阅读:
    ZOJ 3818 Pretty Poem
    HDU 4597 Play Game
    HDU 4497 GCD and LCM
    CSU 1335 高桥和低桥
    UVA 10791 Minimum Sum LCM
    CSU 1119 Collecting Coins
    CSU 1120 病毒
    UVA 12169 Disgruntled Judge
    HDU 1301 Jungle Roads
    POJ 1258 Agri-Net
  • 原文地址:https://www.cnblogs.com/Lanly/p/7297340.html
Copyright © 2011-2022 走看看