HDU5620 KK's Steel(C语言版)

问题链接:HDU5620

刚读到题,有点难解,没有头绪。

看了暗示才明白点,有点像菲波拉契数列,不过每一项求的是数列到该项之和。另外略有不同的是,第1项是1,第2项是2。也许是为了三个钢管围起来不能成为三角形的原因。

既然知道以上这些,那就先打表备查,这是为了节省计算时间,尽管有时候是多余的,但是多数程序都需要打表,那就打表吧。

查找的时候,可以用顺序查找的,只是略费点时间。这里采用二分查找,逻辑就稍微有点麻烦了,因为这不是找相等的数,是找一个小于或等于的数,所以要注意在二分查找之后加以调整。参见:HDU5620 KK‘s Steel(C++语言版)

需要说明的一点是,菲波拉契序列的各项值增长是极快的,其和的增长就更快了,不用95项就达到了所需要的值的范围。这个项数计算,作为定义数组大小的依据,不能随便来的,需要事先做点功课的。

程序如下:

#include <stdio.h>

#define MAXN 95
unsigned long long fsum[MAXN+1];

/* 递推法:计算斐波拉契数列的第1到n项之和 */
/* 这里略有不同,第2项是2,其他基本相同 */
void fibsum(unsigned long long fsum[], int n)
{
    fsum[0] = 0;
    fsum[1] = 1;
    fsum[2] = 3;
    if(n <= 2)
        return;

    unsigned long long f1 = 1, f2 = 2, temp;
    int i;
    for(i=3; i<=n; i++) {
        temp = f1 + f2;
        f1 = f2;
        f2 = temp;

        fsum[i] = fsum[i-1] + temp;
    }
}

int main(void)
{
    // 计算斐波拉契数列的第1到n项之和,打表
    fibsum(fsum, MAXN);

    int t, start, mid, end;
    unsigned long long n;

    scanf("%d",&t);
    while(t--) {
        scanf("%llu",&n);

        // 二分查找
        start = 0;
        end = MAXN;
        for(;;) {
            if(start > end)
                break;
            mid = (start + end) / 2;
            if(fsum[mid] < n)
                start = mid + 1;
            else if(fsum[mid] > n)
                end = mid - 1;
            else if(fsum[mid] == n)
                break;
        }
        if(n < fsum[mid])
            mid--;

        printf("%llu\n", mid);
    }

    return 0;
}



HDU5620 KK's Steel(C语言版)

时间: 2024-10-12 06:41:42

HDU5620 KK's Steel(C语言版)的相关文章

HDU5620 KK&#39;s Steel(C++语言版)

问题链接:HDU5620 刚读到题,有点难解,没有头绪. 看了暗示才明白点,有点像菲波拉契数列,不过每一项求的是数列到该项之和.另外略有不同的是,第1项是1,第2项是2.也许是为了三个钢管围起来不能成为三角形的原因. 既然知道以上这些,那就先打表备查,这是为了节省计算时间,尽管有时候是多余的,但是多数程序都需要打表,那就打表吧. 这个C++版的采用顺序查找,逻辑就要简单一些.参见:HDU5620 KK's Steel(C语言版). 需要说明的一点是,菲波拉契序列的各项值增长是极快的,其和的增长就

CUBUS Suite v4.0-ISO 1CD(土木工程应用软件,多语言版)

Modbus OPC Server v2.7 1CDModScan 32 v4.A00-04 1CDModSim 32 v4.A00-04 1CD 加拿大SES公司产品:CDEGS.2000.v9.4.3-ISO 1CD(电力系统接地分析软件) 美国PTI公司产品:PSS/ADEPT v5.0 1CDPSS E v33.40 1CD(大型电力系统仿真计算软件)PSS/E v32.03-ISO 1CDPSS/E v31.0-ISO 1CDPSS E v31.20 Update Only 1CDPS

《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明

先附上文档归类目录: 课本源码合辑  链接??? <数据结构>课本源码合辑 习题集全解析  链接??? <数据结构题集>习题解析合辑 博主有话说: 01.自学编程,难免思路阻塞,所以从今天起,我(StrayedKing)决定在本博客陆续更新严蔚敏,吴伟民版<数据结构-C语言版>各章节的课本源码和配套习题集答案解析,目的是为了整理数据结构中的知识点,并与网友交流意见,集思广益,共同进步.        ★注★ 左侧随笔分类下用两个栏目:<课本源码>.<习

人事管理系统 c语言版

int menu(){ printf("请按提示输入完成操作!\n"); printf("1.查询员工信息\n"); printf("2.统计员工数量\n"); printf("3.录入员工信息\n"); printf("4.删除员工信息\n"); printf("5.按id排序所有员工\n"); printf("6.打印所有员工信息\n"); printf(&quo

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

51系列小型操作系统精髓 简单实现8 C语言版待改进

使用keil4  ,代码Code Optimization:0   运行OK 可运行8个任务 Program Size: data=21.0 xdata=0 code=401  (包括2个示例变量,未优化) 任务从中断处切换,在定时时间到后从定时中断中切换回来. 待改进地方 1.手动优化汇编程序 2. 重入问题 3.参数进函数和时中断的保护问题 #include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T

51系列小型操作系统精髓 简单实现11 C语言版优化后说明(有图)

/* CRTOS 实时可剥夺型内核 1.任务不用预加载,不用预定义.任务调用时加载,可删除(退出死循环即可) 2.单位轮转查询时间由晶振和定时器初始化决定.在这里为10ms 3.定时时间为[ time*单位轮转查询时间 ] ,其中time为 rtos_wait(time)中time. 4.可运行多个任务[自定义] 5.任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来,任务执行后,回到中断,再从中断回到主程序. */ #include "STC12C5A.H" #d

51系列小型操作系统精髓 简单实现7 C语言版待改进

#include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C  初始10ms #define MAX_TASKS 2 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H. unsigned char idata task_tim

hdu 5620 KK&#39;s Steel(推理)

Problem Description Our lovely KK has a difficult mathematical problem:he has a N(1≤N≤1018) 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. I