JZOJ3461【小麦亩产一千八(kela)】

小麦亩产一千八(kela)

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

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

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

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

这道题是真的水。
设第一个格子放了 P P 个。
很显然可以推系数, f f 为一次项系数, g g 为常数项系数。
很明显这就是个斐波那契数列。

真的很简单啊。

#include <cstdio>
#include <cstring>
using namespace std;

typedef __int128 ll;

const int N = 25;

inline void read(ll &x)
{
    char ch = 0; x = 0;
    for(;ch < '0' || ch > '9';) ch = getchar();
    for(;ch >= '0' && ch <= '9';) x = x * 10 + (ch ^ '0'), ch = getchar();
}

inline void print(ll x) { if(x > 9) print(x / 10); putchar(x % 10 + '0'); }

int a,b;ll x;
ll f[N],g[N],ans;

int main()
{
    f[0] = 1, f[1] = 1, f[2] = 1, g[0] = 1, g[1] = 0, g[2] = 1;
    for(int i = 3;i <= N; ++ i) 
        f[i] = f[i - 1] + f[i -  2], g[i] = g[i - 1] + g[i - 2];
    for(;~scanf("%d",&a);)
    {
        read(x), scanf("%d",&b), x -= g[a]; 
        if(x % f[a]) { printf("-1\n"); continue; }
        ll p = x / f[a];
        print(f[b] * p + g[b]); 
        printf("\n");
    }
    return 0;
}

而且还不用高精度。甚至不用 i n t 128 int128

猜你喜欢

转载自blog.csdn.net/INnovate2030/article/details/102816236
今日推荐