首页 > 技术文章 > 小麦亩产一千八【数论】

hello-tomorrow 2018-07-19 16:29 原文

题目大意:

“有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”。话说HYSBZ(Hengyang School for Boys & Zy)学识渊博孩纸们一讲到粮食,都会想起印度那个著名的故事:国王要在第一个格子里放入一粒小麦,接下来的格子放入前面一个格子的两倍的小麦。这样所需小麦总数是巨大的,哪是不用金坷垃就能完成的任务?不过为了减轻国王的任务,那个下棋获胜的宰相换了一个要求:“我只需要你在棋盘外放一粒小麦,可以将其理解为第0 个格子,然后你需要在第一个格子里放入p粒小麦,之后每一个格子放入前两个格子的小麦数之和的小麦,并且要满足第a 个格子放x 粒小麦,第b 个格子放……”说到这,宰相突然发现自己说的满足第a 个格子放x 粒小麦的情况可能不存在……欺君可是大罪啊!国王看到宰相迟迟不说,自己也烦了!我自己来算!于是国王拜托你,让你算出第b 个格子应该放几粒小麦。当然,就算答案不存在,你也是要告诉国王的。


思路:

可以先推一下。

格子数小麦数
0 1
1 p
2 p+1
3 2p+1
4 3p+2
5 5p+3
6 8p+5
7 13p+8
8 21p+13

很明显,若f[i]为斐波那契数列第ii项,那么第ii个格子有f[i]×p+f[i1]个小麦。 
我们已经知道第a个格子有i个小麦,那么就可以根据上面的公式求出p,再根据上面的公式,即可求出小麦的数量。


代码:

#include <cstdio>
#include <iostream>
using namespace std;

long long a,x,b,p,f[31];

int main()
{
    f[1]=1;
    for (int i=2;i<=28;i++)
     f[i]=f[i-1]+f[i-2];  //求斐波那契数列
    while (scanf("%lld%lld%lld",&a,&x,&b)==3) //多组数据
    {
        if ((x-f[a-1])%f[a])  //如果第a个格子不能放整数个小麦
        {
            printf("-1\n");
            continue;
        }
        p=(x-f[a-1])/f[a];  //计算p
        printf("%lld\n",f[b]*p+f[b-1]);
    }
    return 0;
}

 

推荐阅读