首页 > ACM题库 > HDU-杭电 > hdu 3818-a + b problem-数论-[解题报告]hoj
2015
04-13

hdu 3818-a + b problem-数论-[解题报告]hoj

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
F0 = 0, F1 = 1 and Fn = Fn-1 + Fn-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 = Fk1 + Fk2 + … + Fkm, ki ≥ ki-1 + 2 for 2 ≤ i ≤ m and k1 ≥ 2
For example, 6 can be represented as F2+F5 and 12 can be represented as F2+F4+F6.
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 k1, k2, …, km indicate a Fibonacci formed integer Fk1+Fk2+…+Fkm.
The input will be always correct.

Technical Specification

1. 1 <= T <= 100
2. 1 <= m <= 100
3. 2 <= ki <= 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
2 1 2 2 2 4 3 2 4 6 2 2 5
 


Sample Output
Case 1: 1 5 Case 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");               
     } 
}


版权声明:本文为博主原创文章,未经博主允许不得转载。