• 题目1444:蓝桥杯201 4年第五届真题斐波那契


    这篇文章是帮一个叫做【废柴成长中】的孩子写的。

    题目:

    这里难点应该就是在【输入为一行用空格分开的整数n m p(0

    解析其实不是太麻烦,先分析,然后咱们在一点点的编写出来。

    题目中给的【fib(n) = fib(n+2)-fib(n+1)】这个方法应该分数不高,不然就直接能做出来了。

    我们还得对超大数据进行操作,我这里选用的是【BigInteger】,毕竟这是纯整数,求余计算结果也是纯整数或0,就是计算起来没有直接写符号计算的方便而已。

    看人家给的公式:

    大致先写成这样,反正看的明白就行(Σ(n)f(i))modf(m)

    已知:fib(n) = fib(n+2)-fib(n+1)

    推导:Σf(n) = f(n+2)-1

    推算一下变量m:

    如果 m>=n+2那么f(m)>Σf(n),结果是(f(n+2)-1)%p,

    反之结果为(f(n+2)-1)%f(m)%p==f(n+2)%f(m)%p-1。

    直接上代码,其实很多时候看debug是最快的调试方案:

    1. package com.example.demo2022110201;
    2. /**
    3. * @author
    4. */
    5. import java.math.BigInteger;
    6. import java.util.Scanner;
    7. public class Demo1 {
    8. public static void main(String[] args) {
    9. Scanner sc = new Scanner(System.in);
    10. // 三变量
    11. long n, m, p;
    12. n = sc.nextLong();
    13. m = sc.nextLong();
    14. p = sc.nextLong();
    15. BigInteger bigP = BigInteger.valueOf(p);
    16. if (m >= n + 2) {
    17. BigInteger ans = fib(n + 2, bigP);
    18. System.out.println(ans.mod(bigP).longValue() - 1);
    19. } else {
    20. BigInteger fib_m = fib(m);
    21. BigInteger ans = fib(n + 2, fib_m);
    22. System.out.println(ans.mod(fib_m).mod(bigP).longValue() - 1);
    23. }
    24. sc.close();
    25. }
    26. /**
    27. * 快速矩阵求fib
    28. *
    29. * @param m
    30. * @return
    31. */
    32. private static BigInteger fib(long m) {
    33. BigInteger[][] ans = mPow(m - 2);
    34. return ans[0][0].add(ans[1][0]);
    35. }
    36. private static BigInteger fib(long m, BigInteger mod) {
    37. BigInteger[][] ans = mPow(m - 2, mod);
    38. return ans[0][0].add(ans[1][0]);
    39. }
    40. /**
    41. * 矩阵快速幂
    42. *
    43. * @param n
    44. * @return
    45. */
    46. private static BigInteger[][] mPow(long n) {
    47. BigInteger[][] a =
    48. {{BigInteger.ONE, BigInteger.ONE}, {BigInteger.ONE, BigInteger.ZERO}};
    49. //基础矩阵
    50. BigInteger[][] ans =
    51. {{BigInteger.ONE, BigInteger.ZERO}, {BigInteger.ZERO, BigInteger.ONE}};
    52. while (n != 0) {
    53. if ((n & 1) == 1) {
    54. BigInteger t1 = ans[0][0];
    55. BigInteger t2 = ans[1][0];
    56. ans[0][0] = ans[0][0].multiply(a[0][0]).add(ans[0][1].multiply(a[1][0]));
    57. ans[0][1] = t1.multiply(a[0][1]).add(ans[0][1].multiply(a[1][1]));
    58. ans[1][0] = ans[1][0].multiply(a[0][0]).add(ans[1][1].multiply(a[1][0]));
    59. ans[1][1] = t2.multiply(a[0][1]).add(ans[1][1].multiply(a[1][1]));
    60. }
    61. BigInteger t1 = a[0][0];
    62. BigInteger t2 = a[1][0];
    63. BigInteger t3 = a[0][1];
    64. a[0][0] = a[0][0].multiply(a[0][0]).add(a[0][1].multiply(a[1][0]));
    65. a[0][1] = t1.multiply(a[0][1]).add(a[0][1].multiply(a[1][1]));
    66. a[1][0] = a[1][0].multiply(t1).add(a[1][1].multiply(a[1][0]));
    67. a[1][1] = t2.multiply(t3).add(a[1][1].multiply(a[1][1]));
    68. n >>= 1;
    69. }
    70. return ans;
    71. }
    72. private static BigInteger[][] mPow(long n, BigInteger mod) {
    73. BigInteger[][] a =
    74. {{BigInteger.ONE, BigInteger.ONE}, {BigInteger.ONE, BigInteger.ZERO}};
    75. //基础矩阵
    76. BigInteger[][] ans =
    77. {{BigInteger.ONE, BigInteger.ZERO}, {BigInteger.ZERO, BigInteger.ONE}};
    78. while (n != 0) {
    79. if ((n & 1) == 1) {
    80. //结果乘当前平方
    81. BigInteger t1 = ans[0][0];
    82. BigInteger t2 = ans[1][0];
    83. ans[0][0] = ans[0][0].multiply(a[0][0]).add(ans[0][1].multiply(a[1][0])).mod(mod);
    84. ans[0][1] = t1.multiply(a[0][1]).add(ans[0][1].multiply(a[1][1])).mod(mod);
    85. ans[1][0] = ans[1][0].multiply(a[0][0]).add(ans[1][1].multiply(a[1][0])).mod(mod);
    86. ans[1][1] = t2.multiply(a[0][1]).add(ans[1][1].multiply(a[1][1])).mod(mod);
    87. }
    88. //算平方
    89. BigInteger t1 = a[0][0];
    90. BigInteger t2 = a[1][0];
    91. BigInteger t3 = a[0][1];
    92. //如果是其它语言就换成自己语言的大数处理即可。
    93. a[0][0] = a[0][0].multiply(a[0][0]).add(a[0][1].multiply(a[1][0])).mod(mod);
    94. a[0][1] = t1.multiply(a[0][1]).add(a[0][1].multiply(a[1][1])).mod(mod);
    95. a[1][0] = a[1][0].multiply(t1).add(a[1][1].multiply(a[1][0])).mod(mod);
    96. a[1][1] = t2.multiply(t3).add(a[1][1].multiply(a[1][1])).mod(mod);
    97. n >>= 1;
    98. }
    99. return ans;
    100. }
    101. }

    测试数据,我这没有平台,故而直接用测试用例的【15 11 29】,结果【25】正确

  • 相关阅读:
    配置静态IP地址(centos和ubuntu)
    快速安装Redis以及配置Redis集群
    详细了解一下股票量化交易接口股
    【Python】Python调试器pdb
    [SpringBoot系列]进阶配置
    java编程基础总结——15.包装类
    MATLAB常用命令大全,非常详细(持续更新中)
    springboot系列(十六):如何实现发送邮件提醒,附完整源码(完结篇)
    九、池化层
    Spring Boot 集成 easypoi实现excel的导入导出、excel导入导出含图片
  • 原文地址:https://blog.csdn.net/feng8403000/article/details/128127794