斐波那契数列对10007取余数,求余数的结果

斐波那契数列对10007取余数,求余数的结果

  • 题目:
    问题描述
    Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
    当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
    输入格式
    输入包含一个整数n。
    输出格式
    输出一行,包含一个整数,表示Fn除以10007的余数。
    说明:在本题中,答案是要求Fn除以10007的余数,因此我们只要能算出这个余数即可,而不需要先计算出Fn的准确值,再将计算的结果除以10007取余数,直接计算余数往往比先算出原数再取余简单。
    样例输入
    10
    样例输出
    55
    样例输入
    22
    样例输出
    7704
    数据规模与约定
    1 <= n <= 1,000,000。
  • 思路:
    一开始想的是不安着提示的方法来,是要通过求完斐波那契数列之后,才进行对10007取余数。结果类型给到了long,还是只通过了4到检测,后面就想着先输出前22个数字来,分别对每一个进行取余数,通过这些数列进行寻找规律,然后发现,第22个数字竟然是地20个数字+第21个数字,第23个数字也一样的道理,误以为又成为了另一个斐波那契数列:

      /*
       * 《=20时,不超过10007,不用取余数
       * ==21 刚好超过10007,对其取余数
       * 》=22 变成另一种规则,22=21+20,新的前两个相加的斐波那契数列
       */
      public void solve(int a){
              if(a<3){//1 1直接返回
                  System.out.println(1);
                  return;
              }
              else if(a<=20){//20以内,不用对10007进行取余
                  int [] arr=new int[a+1];
                  arr[1]=arr[2]=1;
                  for(int i=3;i<arr.length;i++){
                      arr[i]=arr[i-1]+arr[i-2];
                  }
                  System.out.println(arr[a]);
    
              }
              else if(a==21){//必须对21进行取余数
                  int [] arr=new int[a+1];
                  arr[1]=arr[2]=1;
                  for(int i=3;i<arr.length;i++){
                      arr[i]=arr[i-1]+arr[i-2];
                  }
                  System.out.println(arr[a]%10007);
              }
              else if(a>=22){//22就等于21+20的数,后面依次类推
                  long [] arr=new long[a+1];
                  arr[20]=6765;
                  arr[21]=939;
                  for(int i=22;i<arr.length;i++){
                      arr[i]=arr[i-1]+arr[i-2];
                  }
                  System.out.println(arr[a]);
              }
    
          }
    

    结果只通过了3个测试案例,居然比原先的还要少。极度郁闷。
    唯有换另外一种想法,10007*x+i=y;怎么可以更简便呢??有时候,觉得灵感真是一瞬间就够了,拉了一泡屎;然后对100个数字进行输出斐波那契的值,以及它的余数,发现到后面的话,long的类型都不够存储,值变为负数了。
    灵感一现,既然不能对最终的数进行对10007取余数,那么我就对每一个斐波那契数列进行取余数,这样的话,那么这个数字肯定不会》10007,所以就有一下的结果

      public void solve2(int a){
          int [] arr=new int[a+1];
          arr[1]=arr[2]=1;
          for(int i=3;i<arr.length;i++){
              arr[i]=(arr[i-1]+arr[i-2])%10007;//对每一个斐波那契数列进行取余数
          }
          System.out.println(arr[a]);
          /*for(int i=1;i<arr.length;i++){
              System.out.print(arr[i]+" ");
              if(i%10==0)
                  System.out.println();
          }*/
      }
    
  • 总结:
    • 找出规律要去验证,别误以为就是答案
    • 将解决方法套到边界进行判断,是否结果正确
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值