山东省第七届ACM大学生程序设计竞赛-Fibonacci

Fibonacci

Time Limit: 2000ms   Memory limit: 131072K  有疑问?点这里^_^

题目描述

Fibonacci numbers are well-known as follow:

 

Now given an integer N, please find out whether N can be represented as the sum of several Fibonacci numbers in such a way that the sum does not include any two consecutive Fibonacci numbers.

输入

Multiple test cases, the first line is an integer T (T<=10000), indicating the number of test cases.

Each test case is a line with an integer N (1<=N<=109).

输出

One line per case. If the answer don’t exist, output “-1” (without quotes). Otherwise, your answer should be formatted as “N=f1+f2+…+fn”. N indicates the given number and f1, f2, … , fn indicating the Fibonacci numbers in ascending order. If there are multiple ways, you can output any of them.

示例输入

4
5
6
7
100

示例输出

5=5
6=1+5
7=2+5
100=3+8+89

提示

 

来源

 “浪潮杯”山东省第七届ACM大学生程序设计竞赛

题目意思:

给一个数N,求出是否有互不相邻的几个斐波那契数相加等于N。

解题思路:

先找到满足小于等于n的最大斐波那契数,再依次递减寻找下一个满足条件的数。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define MAXN 1001
int f[50],a[50];//分别表示保存斐波那契数列、求和的各项
void fun()//斐波那契数列打表
{
    f[0]=1,f[1]=2;
    for(int i=2; i<50; ++i)
        f[i]=f[i-1]+f[i-2];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t,flag,cnt;
    cin>>t;
    fun();
    memset(a,0,sizeof(a));
    while(t--)
    {
        int i,j,n;
        flag=cnt=0;
        cin>>n;
        for(i=0; i<50; ++i)//找到满足小于等于n的最大斐波那契数
            if(n<=f[i])
            {
                cout<<n<<"=";
                if(n==f[i]) a[cnt++]=f[i];
                else
                {
                    --i;
                    a[cnt++]=f[i];
                }
                flag=1;//flag标记是否存在求和序列
                n-=f[i];
                break;
            }
        for(j=i-1; j>=0; --j)//i-1是因为不能相邻
        {
            if(n>=f[j])
            {
                n-=f[j];
                a[cnt++]=f[j];
                --j;
            }
        }
        if(!flag) cout<<"-1"<<endl;//不存在
        else
        {
            for(i=--cnt; i>0; --i)
                cout<<a[i]<<"+";
            cout<<a[0]<<endl;
        }
    }
    return 0;
}
/*
4
5
6
7
100
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值