设为首页 加入收藏

TOP

斐波那契数列(二)(一)
2023-07-23 13:29:52 】 浏览:64
Tags:那契数

        斐波那契数列在很多问题上得到了应用。下面通过一些具体的实例加以说明。

【例1】钢管切割

问题描述

给一根长度为n的钢管,问最多能切割成几段钢管,使得截成的钢管互不相等且均不能构成三角形。

输入

输入文件的第一行包含整数T(1≤T≤10) ,表示测试用例的数量。

每个测试用例包含一行,包括整数N(1≤N≤1018)表示钢管的长度。

输出

对于每个测试用例,输出一行,一个整数表示它可以切割成的最大段数。

输入样例

1

6

输出样例

3

        (1)编程思路。

        本题是斐波那契数列的典型应用。

        下面先以长度为150的钢管切割为例进行说明。

        由于形成三角形的充要条件是任何两边之和大于第三边,因此不构成三角形的条件就是存在两边之和不超过另一边。而要将钢管切割出的段数更多,则开始应尽可能切割出满足要求的长度最短的钢管,因此开始可以切割出一根长度为1和一根长度为2的两根钢管(切割出的钢管长度互不相同),第3根钢管的长度应该是3(为了使得切割的段数最大,因此要使剩下来的钢管尽可能长,因此每一根钢管总是前面的相邻2根钢管长度之和),之后依次为:1、2、3、5、8、13、21、34、55,以上各数之和为 142,与 150 相差 8,因此可以取最后一段钢管长度为 63,这时段数达到最大为 9。

       在这个示例中,142是斐波那契数列的前项和,我们要把150超出142的部分加到最后的一个数上去,如果加到其他数上,就有3根钢管可以构成三角形了。

        (2)源程序。

#include <stdio.h>
int main()
{
    long long f[110]={0,1,2},fsum[110]={0,1,3};
    int i;
    for (i=3; i<100; i++)
    {
        f[i] = f[i-1] + f[i-2];
        fsum[i] = fsum[i-1] + f[i];
    }
    int t;
    scanf("%d",&t);
    while (t--)
    {
        long long n;
        scanf("%lld",&n);
        for (i=1; i<100; i++)
        {
            if (fsum[i] == n)
            {
                break;
            }
            else if (fsum[i]>n)
            {
                i--;
                break;
            }
        }
        printf("%d\n",i);
    }
    return 0;
}

        将上面的源程序提交给HDU题库 HDU 5620 KK's Steel  (http://acm.hdu.edu.cn/showproblem.php?pid=5620),可以Accepted。

【例2】三角形

问题描述

给定n根直棒,能否在这n根直棒中找出3根棒子组成一个三角形。

输入

输入有多个测试用例。

每个测试用例都以包含整数n的行开始(1≤n≤106),这表示直棒的数量,然后是n个正整数(小于231?1) 用空格隔开。

输出

每个用例输出YESNO表示可以或不能用三根直棒组成一个三角形。

输入样例

4

1 2 3 4

输出样例

YES

          (1)编程思路。

         由例1可知,三角形的三边关系定理和斐波那契数列存在着一定的联系。由于斐波拉契数列级别增长很快,因此若n>=50,肯定可以找到3根直棒组成三角形。

         如果不能组成三角形,输入数的个数 n< 50。将这n个数从小到大排序,排序后,再遍历这n个数,若存在相邻两个数的和大于之后的1个数,即存在a[i-2]+a[i-1]>a[i],则这3根直棒可以组成三角形。

        (2)源程序。

#include <stdio.h>
int main()
{
    int n;
    while (scanf("%d",&n)!=EOF)
    {
        int i,j;
        int flag = 0;
        if (n < 50)
        {
            int a[50];
            for (i = 0; i < n; i++)
               scanf("%d", &a[i]);
            for (i=0;i<n-1;i++)
                for (j=0;j<n-1-i;j++)
                   if (a[j]>a[j+1])
                   {
                      int tmp;
                      tmp=a[j]; a[j]=a[j+1]; a[j+1]=tmp;
                   }
            for (i = 0; i < n - 2; i++)
               if (a[i]+a[i+1]>a[i+2]) { flag = 1; break; }
        }
        else
        {
            int x;
            for (i = 0; i < n; i++)
               scanf("%d", &x);
            flag = 1;
        }
        if (flag) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

      将上面的源程序提交给HDU题库 HDU 6512 Triangle  (http://acm.hdu.edu.cn/showproblem.php?pid=6512),可以Accepted。

【例3】不包含相邻1的序列

问题描述

给定正整数n,确定在长度为n的0、1序列中不包含相邻1的序列的数量。例如,对于n=3,答案是5(序列000、001、010、100、101满足要求,而011、110、111是不满足要求的)。

输入

第一行包含测试用例的数量。

对于每一个测试用例,在一行中单独给定一个小于45的正整数。

输出

每个测试用例的输出都以包含“Scenario #i:”的行开始,其中i是从1开始的测试用例数。然后输出一行,其中包含没有相邻1的n位序列个数。用空行终止方案的输出。

输入样例

2

3

1

输出样例 

Scenario #1:

5

 

Scenario #2:

2

        (1)编程思路。

        设a[i]表示长度为i的0、1序列中不包含相邻1的序列的数量,在长度为 i 的序列后面再加上1位可以构成长度为 i+1 的序列。若后面添加0,直接添加在长度为i的序列后面即可,有a[i]种序列;若后面添加1,则前面只能为0,即在长度为i-1的合法序列后面添加01,有a[i-1]种序列。 因此,a[i+1]=a[i]+a[i-1]。也就是斐波那契数列。

        (2)源程序。

#include <stdio.h>
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇BC3-牛牛学说话之-整数 下一篇网易云VIP音乐NCM文件转MP3,C语言..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目