小麦亩产一千八【数论】
题目大意:
“有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”。话说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[i−1]个小麦。
我们已经知道第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; }