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