题目链接:
题目
“有了金坷垃,肥料一袋能顶两袋撒,小麦亩产一千八,吸收两米下的氮磷钾……”,话说学识渊博孩纸们一讲到粮食,都会想起印度那个著名的故事:国王要在第一个格子里放入一粒小麦,接下来的格子放入前面一个格子的两倍的小麦。这样所需小麦总数是巨大的,哪是不用金坷垃就能完成的任务?不过为了减轻国王的任务,那个下棋获胜的宰相换了一个要求:“我只需要你在棋盘外放一粒小麦,可以将其理解为第 个格子,然后你需要在第一个格子里放入 粒小麦,之后每一个格子放入前两个格子的小麦数之和的小麦,并且要满足第 个格子放 粒小麦,第 个格子放……”说到这,宰相突然发现自己说的满足第 个格子放 粒小麦的情况可能不存在……欺君可是大罪啊!国王看到宰相迟迟不说,自己也烦了!我自己来算!于是国王拜托你,让你算出第 个格子应该放几粒小麦。当然,就算答案不存在,你也是要告诉国王的。
输入
该题有多组数据,请读到文件末结束。
对于每一组数据仅一行, 个正整数 , , ,分别表示第 个格子放了 粒小麦,以及你所需要计算的是第 个格子的小麦数量。
输出
对于每一次询问,仅 个整数,为第 个格子的小麦数量,若宰相说的情况不存在,那么请输出。
样例输入
1 1 2
3 5 4
3 4 6
12 17801 19
样例输出
2
8
-1
516847
样例解释
对于样例二, 时,能够满足,因此宰相没有撒谎,此时第 个格子的小麦数应为
数据范围
对于的数据:如果答案存在,那么
对于的数据:数据组数,, 数据保证如果答案存在,那么
思路
这道题其实㐊一道变了形的斐波那切数列。
设为第个格子应该放的数量,那我们简单模拟一下:
那我们又发现,设原来的斐波那契数列中的第个,式子为,则其实是,其实是,那就可以得到这个:
简单移一下项,就可以得到这个:
那我们就可以先预处理原来的斐波那契数列,然后对于每一组数据,通过与套入公式中求出(如果不是整数则没有解),然后用和代回公式中,就可以求出答案了。
(注意,要用)
代码
#include<cstdio>
#define ll long long
using namespace std;
ll a, x, b, fb[21];
int main() {
fb[1] = 0;
fb[2] = fb[3] = 1;//初始化
for (int i = 4; i <= 21; i++)
fb[i] = fb[i - 1] + fb[i - 2];//求出原来的斐波那契数列
while (~scanf("%lld %lld %lld", &a, &x, &b)) {//读入
ll p = (x - fb[a]) / fb[a + 1];//求出p值
if ((x - fb[a]) % fb[a + 1]) printf("-1\n");//没有解
else printf("%lld\n", fb[b + 1] * p + fb[b]);//有解直接算出答案
}
return 0;
}