小麦亩产一千八(kela)

(kela)小麦亩产一千八(kela)

题目链接:jzoj 3461jzoj\ 3461

题目

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

输入

该题有多组数据,请读到文件末结束。

对于每一组数据仅一行,33 个正整数aa , xx , bb ,分别表示第 aa 个格子放了 xx 粒小麦,以及你所需要计算的是第 bb 个格子的小麦数量。

输出

对于每一次询问,仅 11 个整数,为第 bb 个格子的小麦数量,若宰相说的情况不存在,那么请输出1-1

样例输入

1 1 2

3 5 4

3 4 6

12 17801 19

样例输出

2

8

-1

516847

样例解释

对于样例二,f[1]=2f[1]=2 时,能够满足f[3]=5f[3]=5,因此宰相没有撒谎,此时第 55 个格子的小麦数应为f[4]=f[2]+f[3]=3+5=8.f[4]=f[2]+f[3]=3+5=8.

数据范围

对于50%50\%的数据:如果答案存在,那么p<=50p<=50

对于100%100\%的数据:1<=1<=数据组数<=10000<=100001<=a,b<=201<=a,b<=20, 数据保证如果答案存在,那么1<=p<=1000000.1<=p<=1000000.

思路

这道题其实㐊一道变了形的斐波那切数列。

f[i]f[i]为第ii个格子应该放的数量,那我们简单模拟一下:
f[0]=1f[0] = 1
f[1]=pf[1] = p
f[2]=f[0]+f[1]=1+pf[2] = f[0] + f[1] = 1 + p
f[3]=f[1]+f[2]=p+(1+p)=1+2pf[3] = f[1] + f[2] = p + (1 + p) = 1 + 2 * p
f[4]=f[2]+f[3]=(1+p)+(1+2p)=2+3pf[4] = f[2] + f[3] = (1 + p) + (1 + 2 * p) = 2 + 3 * p
f[5]=f[3]+f[4]=(1+2p)+(2+3p)=3+5pf[5] = f[3] + f[4] = (1 + 2 * p) + (2 + 3 * p) = 3 + 5 * p
那我们又发现,设fb[i]fb[i]原来的斐波那契数列中的第ii个,式子为f[i]=j+kpf[i] = j + k * p,则jj其实是fb[i]fb[i]kk其实是fb[i+1]fb[i + 1],那就可以得到这个:
f[i]=fb[i]+fb[i+1]p              f[i] = fb[i] + fb[i + 1] * p\ \ \ \ \ \ \ \ \ \ \ \ \ \ ①
简单移一下项,就可以得到这个:
p=(f[i]fb[i]) / fb[i+1]              p = (f[i] - fb[i])\ /\ fb[i + 1]\ \ \ \ \ \ \ \ \ \ \ \ \ \ ②

那我们就可以先预处理原来的斐波那契数列,然后对于每一组数据,通过aaxx套入公式中求出pp(如果pp不是整数则没有解),然后用ppbb代回公式中,就可以求出答案了。

(注意,要用long longlong\ long

代码

#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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章