HDU 3818 A + B Problem 简单数论题

时间:2022-12-31 15:06:55

A + B Problem

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 458    Accepted Submission(s): 153


Problem Description
Do you know the famous Fibonacci sequence? It is defined by the recurrence
F 0 = 0, F 1 = 1 and F n = F n-1 + F n-2 for n ≥ 2.
The Fibonacci numbers have many interesting properties. One of them is that the Fibonacci numbers can be used to represent integers. Every positive integer has a unique representation of the form
n = F k1 + F k2 + … + F km, k i ≥ k i-1 + 2 for 2 ≤ i ≤ m and k 1 ≥ 2
For example, 6 can be represented as F 2+F 5 and 12 can be represented as F 2+F 4+F 6.
Now you know how to represent positive integers with the Fibonacci numbers, can you add them? Given two Fibonacci formed integers, you should calculate the sum of them.
 

Input
The first line contains a single integer T, indicating the number of test cases.
Each test case contains two lines; each line contains a single integer m followed by m integers k 1, k 2, …, k m indicate a Fibonacci formed integer F k1+F k2+…+F km.
The input will be always correct.

Technical Specification

1. 1 <= T <= 100
2. 1 <= m <= 100
3. 2 <= k i <= 1000000
 

Output
For each test case, output the case number first, then a single line indicates the sum of the two Fibonacci formed integer. The sum should be Fibonacci formed like the input.
 

Sample Input
 
 
21 22 2 43 2 4 62 2 5
 

Sample Output
 
 
Case 1:1 5Case 2:2 5 7
 

算法:

主要是调用两个公式   f[n]=f[n-1]+f[n-2]

             下一个公式  2*f[n]=f[n-2]+f[n+1]

这两个公式进行求解 要注意的是 输出结果序号的最小间隔为2

要注意的是 2 3 5

                 2 3 5

这种特殊的情况 出现了 序号 1   得出f[1]=f[2]的结果。


#include<stdio.h>
#include<string.h>
#define MAX 1000000
int a[1000010];
int b[1000];
int main()
{
int x,n,i,j,num,max=0,sum,ji=0;
scanf("%d",&x);
while(x--)
{
ji++;
memset( a, 0, sizeof(a) ); //输入数据
for( i=1; i<=2; i++ )
{
scanf("%d",&n);
for( j=1; j<=n;j++ )
{
scanf("%d",&num);
if( num>max )max=num;
a[num]++;
}
}


for( i=max; i>=2; i--) //对含有两个重复利用 2*f[n]=f[n+1]+f[n-2]
{
if(a[i]>=2){
a[i]-=2;
a[i+1]+=1;
a[i-2]+=1;
}
}

if(a[1]!=0)a[2]+=a[1]; //考虑 fibnaci数列中 序号 f[1]=f[2]这种特殊情况

for( i=max+1; i>=3; i-- ) //连续两次调用f[n]=f[n-1]+f[n-2]
{
if(a[i]==1&&a[i-1]==1)
{
a[i]=a[i-1]=0;
a[i+1]+=1; ;
}
}


for( i=max+2; i>=3; i-- )
{
if(a[i]==1&&a[i-1]==1)
{
a[i]=a[i-1]=0;
a[i+1]+=1; ;
}
}


j=0;
sum=0;
for(i=2; i<=max+5; i++) //输出结果
{
if(a[i]!=0){b[j++]=i;sum++;}
}
printf("Case %d:\n",ji);
printf("%d",sum);
for( i=0; i<j; i++)
printf(" %d",b[i]);
printf("\n");
}
}