zoukankan      html  css  js  c++  java
  • 小麦亩产一千八

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


    【输入格式】kela.in
    该题有多组数据,请读到文件末结束。
    对于每一组数据仅一行,3 个正整数a,x,b,分别表示第a 个格子放了x 粒小麦,以及你所需要计算的是第b 个格子的小麦数量。


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


    样例输入
    1 1 2
    3 5 4
    3 4 6
    12 17801 19

    样例输出
    2
    8
    -1
    516847


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


    【数据范围与约定】
    对于50%的数据:如果答案存在,那么p<=50
    对于100%的数据:1<=数据组数<=10000,1<=a,b<=20, 数据保证如果答案
    存在,那么1<=p<=1000000.(注:p 是第一格放置的小麦数)。

    “然后你需要在第一个格子里放入若干小麦,之后每一个格子放入前两个格子的小麦数之和的小麦”,看到这句话就感觉特别亲切,一看就是知道是和斐波那契切数列有关的。不过这道题不告诉你第一项是多少,而是通过后面的第几项是多少来反推。

    无脑的算法就是枚举第一项,然后检验。嗯……不过再怎么优化,出发点是在不动脑子的前提下的,都不是最优。

    那么什么是最优呢?读读题,我们发现,已知的只有f[0] = 1 和,f[a] = x。而我们要求f[1]。那么就可以试着推一下用 f[0] 和 f[1] 来表示 f[2], f[3], f[4]……

          f[2] = f[1] +f[0];

          f[3] = 2 * f[1] + f[0];

          f[4] = 3 * f[1] + 2 * f[0];

          f[5] = 5 * f[1] + 3 * f[0];

          ……

    于是有了一个惊奇的发现:对于任意的f[n] 都可以用f[1] 和 f[0] 来表示,而且 f[1] 前的系数是斐波那契的第 n 项,f[0] 前的系数是第(n - 1) 项。

    而这道题f[0] = 1,所以对于有没有解,只用判断x - f[a - 1]能否被 f[a] 整除。能的话就输出 f[b] * (x - f[a - 1]) + f[b - 1]。

     1 #include<cstdio>
     2 #include<iostream> 
     3 #include<cstring> 
     4 #include<cmath>
     5 #include<algorithm> 
     6 #include<vector>
     7 #include<queue>
     8 using namespace std;
     9 typedef long long ll;
    10 const int maxn = 50;
    11 ll f[maxn];
    12 void init()
    13 {
    14     f[0] = 0; f[1] = 1;        //预处理斐波那契 
    15     for(int i = 2; i < maxn; ++i) f[i] = f[i - 1] + f[i - 2];
    16 }
    17 int main()
    18 {
    19     freopen("kela.in", "r", stdin);
    20     freopen("kela.out", "w", stdout);
    21     init();
    22     ll a, x, b;
    23     while(scanf("%lld%lld%lld", &a, &x, &b) != EOF)
    24     {
    25         ll f1 = x - f[a - 1];
    26         if(f1 % f[a] || f1 < 0) {printf("-1
    "); continue;}
    27         f1 /= f[a];
    28         printf("%lld
    ", f[b] * f1 + f[b - 1]); 
    29     }
    30     return 0;
    31 }
  • 相关阅读:
    多线程创建方式及线程安全问题
    JDBC连接池&DBUtils
    mySQL 多表查询语句
    git 本机链接多库配置
    mysql类似递归的一种操作进行层级查询
    js 自定义事件观察者模式(发布/订阅)
    CSS样式遇见的问题总结记录
    maven打包pom.xml备忘
    JasperReports实现报表调出excel
    ActiveMQ 集群配置 高可用
  • 原文地址:https://www.cnblogs.com/mrclr/p/8922687.html
Copyright © 2011-2022 走看看