題目鏈接:
題目
“有了金坷垃,肥料一袋能頂兩袋撒,小麥畝產一千八,吸收兩米下的氮磷鉀……”,話說學識淵博孩紙們一講到糧食,都會想起印度那個著名的故事:國王要在第一個格子裏放入一粒小麥,接下來的格子放入前面一個格子的兩倍的小麥。這樣所需小麥總數是巨大的,哪是不用金坷垃就能完成的任務?不過爲了減輕國王的任務,那個下棋獲勝的宰相換了一個要求:“我只需要你在棋盤外放一粒小麥,可以將其理解爲第 個格子,然後你需要在第一個格子裏放入 粒小麥,之後每一個格子放入前兩個格子的小麥數之和的小麥,並且要滿足第 個格子放 粒小麥,第 個格子放……”說到這,宰相突然發現自己說的滿足第 個格子放 粒小麥的情況可能不存在……欺君可是大罪啊!國王看到宰相遲遲不說,自己也煩了!我自己來算!於是國王拜託你,讓你算出第 個格子應該放幾粒小麥。當然,就算答案不存在,你也是要告訴國王的。
輸入
該題有多組數據,請讀到文件末結束。
對於每一組數據僅一行, 個正整數 , , ,分別表示第 個格子放了 粒小麥,以及你所需要計算的是第 個格子的小麥數量。
輸出
對於每一次詢問,僅 個整數,爲第 個格子的小麥數量,若宰相說的情況不存在,那麼請輸出。
樣例輸入
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;
}