【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 }

神奇的代码

时间: 2024-10-16 00:57:05

【NOI2015模拟8.14】A+B的相关文章

Cisco PT模拟实验(14) 路由器OSPF动态路由的配置

Cisco PT模拟实验(14) 路由器OSPF动态路由的配置 实验目的: 掌握OSPF动态路由选择协议的配置方法 掌握路由选择表中的OSPF路由描述 熟悉路由选择和分组转发的原理及过程 实验背景: 公司通过一台三层交换机连到企业网的出口路由器上,路由器再与互联网服务提供商 ISP的另一台路由器连接.现要企业网设备上做适当配置,实现企业网内部主机与外网主机之间的相互通信.为了简化网管的管理维护工作,公司决定采用动态路由配置 -- OSPF协议实现互通. 技术原理: 路由器通过路由选择协议建立了一

JZOJ.5274【NOIP2017模拟8.14】数组

Description Input Output Sample Input 输入样例1: 3 2 7 5 4 2 输入样例2: 5 3 1 5 4 3 5 5 Sample Output 输出样例1: 999999732 输出样例2: 0 Data Constraint 这个题要求乘积最小,显然我们希望乘积是负数是最好的,然后就是让这个负数的绝对值尽可能的大. 对于一堆数相乘,绝对值最小的对这个结果影响是最大的,所以我们就每次让绝对值最小的,如果是正数就加上x,负数就减去x,用个优先队列维护绝对

noip模拟赛#14

#14: T1:f[x]=x-1(x&1)||x/2(x&1=0) 求[n,m]有多少个数可以通过变换得到k.(1e9). =>好像cf上看过类似的题,用二进制的方式来写.不过我没有考虑111的情况算出来的是110的结果.所以WA了.而且也写的非常复杂. =>T1难度一般不大应好好的想想. T2:(n,m)有向图,可有自环和重边,求多少种方案使得从(1,n)至少经过n-1条边. =>组合数学(线性求逆元或费马小定理求逆元).我不会隔板法求组合数所以不会. 隔板法:http

[考试反思]0131省选模拟测14:遗失

100+0+40=140.rk3 凑合? 然而T2调试语句没删丢了20.(代码开头读入之前一个赫然的return 0) T2大概转化了题意,然后是杨氏矩阵的裸体了.然而我不会杨氏矩阵. 尽力了.能打的都打了.还不错吧... 中午就改完了T2,然后对着T3看了差不多一下午... 感觉题解有锅啊...并没有人会解释...于是弃掉了 T1:开车 大意:图,第i条边权值为$2^i$.求每条边都经过一次的最短回路.$n \le 100000, m \le 500000$ 先强制每条边都走一次,于是每个点度

[XJOI NOI2015模拟题13] A 神奇的矩阵 【分块】

题目链接:XJOI NOI2015-13 A 题目分析 首先,题目定义的这种矩阵有一个神奇的性质,第 4 行与第 2 行相同,于是第 5 行也就与第 3 行相同,后面的也是一样. 因此矩阵可以看做只有 3 行,从上到下就是 1 2 3 2 3 2 3 ...... 然后我们使用分块,将每一行分成 sqrt(m) 大小的块. 然后维护 A[i][j] —— 第一行前 i 块中,数字 j 的出现次数. 同时维护 B[i][j] —— 第二行前 i 块中,数字 j 的出现次数. 这里要将第一行的数字进

[XJOI NOI2015模拟题13] C 白黑树 【线段树合并】

题目链接:XJOI - NOI2015-13 - C 题目分析 使用神奇的线段树合并在 O(nlogn) 的时间复杂度内解决这道题目. 对树上的每个点都建立一棵线段树,key是时间(即第几次操作),动态开点. 线段树的节点维护两个值,一个是这段时间内的 1 操作个数,另一个是这段时间内变化的黑色节点权值和. 在处理所有操作的时候,每棵线段树都是仅代表树上的一个点,因此线段树的每个节点维护的就是这段时间内以这个点为 a 的 1 操作个数和这段时间内这个点的黑色节点权值和(这个点 x 由黑变白就 -

[XJOI NOI2015模拟题13] B 最小公倍数 【找规律】

题目链接:XJOI - NOI2015-13 - B 题目分析 通过神奇的观察+打表+猜测,有以下规律和性质: 1) 删除的 n 个数就是 1~n. 2) 当 c = 2 时,如果 n + 1 是偶数,答案是 lcm(n + 1, (n + 1) / 2 * 3) = 3(n + 1),如果 n + 1 是奇数,答案是 lcm(n + 2, (n + 2) / 2 * 3) = 3(n + 2). 注意特判 n = 2 和 n = 4 的情况,这些情况下 (n + 1) / 2 * 3 或 (n

【NOIP2016提高A组模拟8.14】传送带

题目 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段AB和线段CD.FTD在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R.现在FTD想从A点走到D点,他想知道最少需要走多长时间 分析 易得,答案就是首先在AB上走一段,然后走到CD上的一点,再走到D. 正解就是三分套三分,但本人很懒,打了个枚举加三分,勉强卡了过去. 首先在AB上枚举一点,接着在CD上按时间三分. #include <cmath> #include <iostrea

【NOIP2016提高A组模拟8.14】疯狂的火神

题目 火神为了检验zone的力量,他决定单挑n个人. 由于火神训练时间有限,最多只有t分钟,所以他可以选择一部分人来单挑,由于有丽子的帮助,他得到了每个人特定的价值,每个人的价值由一个三元组(a,b,c)组成,表示如果火神在第x分钟单挑这个人(x指单挑完这个人的时间),他就会得到a-b*x的经验值,并且他需要c分钟来打倒这个人. 现在火神想知道,他最多可以得到多少经验值,由于火神本来就很笨,进入zone的疯狂的火神就更笨了,所以他希望你来帮他计算出他最多可以得到多少经验值. 分析 注意到这道题有