描述
题解
首先我们来分析一下斐波那契数列的基本性质,众所周知,斐波那契数列从第二项开始后,能够组合(每一项只有选与不选两种操作)出来任意自然数,所以才会有这个特殊表示法的存在,并且这个表示法里不存在任意两个连着的
1
,因为一旦存在就可以转化为另一个数,毕竟
至此,我们来考虑两个序列叠加在一起后可能存在的情况。首先
但是此时提交还会有
bug
,这也是这道题
AC
率那么低的原因,有些地方不容易想到,下载数据一看会发现自己漏考虑情况了。不容易想到的地方大致有两点,一是存在大于
2
的情况发生,这个是因为当我们在进行第一个转化过程时,会有加项操作,所以会出现大于
可以加上输入输出外挂优化一下,我比较懒,只是将输出部分先存在字符串然后统一输出了一下,节约了一些时间,输入的时候也可以整行读入然后处理一下,比较容易,但是架不住我懒。
代码
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 1e6 + 5;
int n, m;
int a[MAXN];
int b[MAXN];
char c[MAXN << 1];
int main()
{
scanf("%d", &n);
getchar();
for (int i = 0; i < n; i++)
{
a[i] = getchar() - '0';
getchar();
}
scanf("%d", &m);
getchar();
for (int i = 0; i < m; i++)
{
a[i] += getchar() - '0';
getchar();
}
// 逆着扩展一遍
n = max(m, n);
for (int i = n - 1; i > 1; i--)
{
if (a[i] >= 2)
{
// ex: 2 * 5 = 8 + 2
a[i] -= 2;
a[i - 2] += 1;
a[i + 1] += 1;
n = max(i + 2, n);
}
if (a[i] >= 1 && a[i - 1] >= 1)
{
// ex: 2 + 3 = 5
a[i] -= 1;
a[i - 1] -= 1;
a[i + 1] += 1;
n = max(i + 2, n);
}
}
// 处理边界特殊情况
if (a[0] >= 2 && a[1] == 0)
{
// ex: 1 + 1 = 2
a[0] -= 2;
a[1] += 1;
}
else if (a[1] == 3)
{
// ex: 2 + 2 + 2 = 1 + 2 + 3
a[1] -= 1;
a[0] += 1;
a[2] += 1;
}
// 正着扩展若干遍,一直到无法扩展
int flag = 1;
while (flag)
{
flag = 0;
for (int i = 0; i < n; i++)
{
if (a[i] >= 1 && a[i + 1] >= 1 && a[i + 2] != 1)
{
flag = 1;
// ex: 2 + 3 = 5
a[i] -= 1;
a[i + 1] -= 1;
a[i + 2] += 1;
n = max(i + 3, n);
}
}
}
int cnt = 0;
for (int i = 0; i < n; i++)
{
c[cnt++] = a[i] + '0';
if (i != n - 1)
{
c[cnt++] = ' ';
}
}
c[cnt] = '\n';
printf("%d\n%s", n, c);
return 0;
}