問題描述
對於每個數字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大。
你的任務很簡單,給你兩個用斐波拉切數最大化表示的兩個數字,輸出他們相加後用斐波那契最大化表示的數字。
輸入
兩行,分別表示兩個數字
每一行開頭一個n,表示長度
然後緊接着n個數字,爲從低位到高位。
輸出
同輸入格式。一行。
樣例輸入
4 0 1 0 1
5 0 1 0 0 1
樣例輸出
6 1 0 1 0 0 1
算法討論
嘛我們找找規律,發現了神奇的進位方式,當相加後第i位大於等於2時,第i位減2,i+1位加1,當i-2大於0時第i-2位加1,否則當i-1位大於0時第i-1位加1。當第i位和第i+1位都等於1時,第i、i+1位減1,第i+2位加1.
#include <cstdio>
using namespace std;
#define maxn 1000006
int a[maxn],b[maxn],c[maxn];
int n,n1,n2;
int max(int a,int b)
{
return a>b?a:b;
}
bool check()
{
for (int i=1;i<=n;i++)
if (a[i]==a[i+1] && a[i]!=0 || a[i]>=2)
return 0;
return 1;
}
int work()
{
int t=n;
for (int i=t;i>=1;i--)
{
if (a[i]==0)
continue;
if (a[i]>=2)
{
a[i+1]+=1;
if (i==2)
a[i-1]+=1;
else
if (i!=1)
a[i-2]+=1;
a[i]-=2;
if (i+1>n)
n=i+1;
}
if (a[i]==1 && a[i-1]==1)
{
a[i+1]+=1;
a[i]--; a[i-1]--;
if (i+1>n)
n=i+1;
}
}
}
int main()
{
scanf("%d",&n1);
for (int i=1;i<=n1;i++)
scanf("%d",&a[i]);
scanf("%d",&n2);
for (int i=1;i<=n2;i++)
{
scanf("%d",&b[i]);
a[i]+=b[i];
}
n=max(n1,n2);
while (!check())
work();
printf("%d ",n);
for (int i=1;i<=n;i++)
printf("%d ",a[i]);
}