hdu KK's Steel【思维】【斐波那契数列应用】

KK's Steel

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 162    Accepted Submission(s): 73


Problem Description
Our lovely KK has a difficult mathematical problem:he has a N(1N1018) meters steel,he will cut it into steels as many as possible,and he doesn't want any two of them be the same length or any three of them can form a triangle.
 


Input
The first line of the input file contains an integer T(1T10) , which indicates the number of test cases.

Each test case contains one line including a integer N(1N1018) ,indicating the length of the steel.
 


Output
For each test case, output one line, an integer represent the maxiumum number of steels he can cut it into.
 


Sample Input
  
  
1 6
 


Sample Output
  
  
3
Hint
1+2+3=6 but 1+2=3 They are all different and cannot make a triangle.


说实话,题目拿到手上的时候,真的想了半天如何暴力优化之类的思路去做,但是如何暴力都做不到,dfs应该能做,但是绝对会超时、因为我唯一能想到的东西就是枚举,既然行不通,那么就得换路子、在纸上比比划划弄了半天,还是没有思路、

最后没办法,直接枚举边界边吧、我这里枚举了 1 2 3一组、2 3 5一组、完事合计下一组是3 5 8、我盯着这几个数合计半天,也记不住啥时候灵机一动,草泥马、这特喵的是斐波那契数列啊、边界是斐波那契数列组成的、现在加入给我一个6,我能分割出1 2 3,如果给我一个7,我就能分割出 1 2 4、扩大最大边,一样能达到目的、所以这个时候就开始敲代码实现了、注意数据范围,这里尽量自己去测试一下数组要开多大,也不用担心是大精度、10^18并没有2^63-1大、另外注意,数据要用long long int

这里上AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
#define ll long long int
ll f[100];
ll sum[100];
int main()
{
    f[1]=1;
    sum[1]=1;
    f[2]=2;
    sum[2]=3;
    int i;
    for(i=3;i<=90;i++)
    {
        f[i]=f[i-1]+f[i-2];
        sum[i]=sum[i-1]+f[i];
    }
    int t;
    scanf("%d",&t);
    while(t--)
    {
        ll n;
        scanf("%I64d",&n);
        if(n==1||n==2)//注意这里1、2不能分割,所以输出1、3-5是输出2,就这几个特殊的数据有的时候会疏忽、尤其是2、斐波那契数列中有2、因为这两个数据hack掉好几个人、
        {
            printf("1\n");
            continue;
        }
        int i;
        ll sum=0;
        for(i=1;i<=90;i++)
        {
            sum+=f[i];
            if(sum==n)
            {
                printf("%d\n",i);
                break;
            }
            if(sum>n)
            {
                printf("%d\n",i-1);
                break;
            }
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值