你能打开这把密码锁吗?

 
开锁的经验大家都有,但是眼前这把锁不太好开,我们看看它
1 3 5   ( )
1 4 9   ( )
5 8 13 ( )
… … … ( )
凭借你多年的开锁经验,你马上断定眼前这扇门用的是密码锁。只见锁身上有 n行数字,在每行数字末尾都有好几个数字拨盘。看着这一行行多少不一的数字和数字末尾留下的空格,你忽然想起了小时候经常玩的一个游戏:找规律。这个游戏就是给你一个数列的前几项,让你填出后一项,例如: 2 4 6 ( 8 )   1 4 9 ( 16 )
在玩游戏的过程中,你发现了一个窍门,所有这类问题,都可以用这种方法解决:对于一个已知前 m项的数列 al , a2 , a3am,一定可以找到惟一一个不超过m-1次的多项式f(x),使得 f ( l ) = a1 , f ( 2 ) = a2 f ( m ) = am,那么 f ( m + 1)就是要找的下一项。
现在你决定用这种方法试着打开眼前这把密码锁。
到这里,我们都想到了初中学的数列知识,但是如果数字很多的话,也就是问题的规模变大的话,我们是不是就只能等着知道密码的人来开了呢?
等知道密码的人来开锁的确是个不错的主意,但是这样的话偶也就不用发这个帖子了。(暂时还不清楚blog的文章应该叫什么,汗……)我们先看一下这个数列的通项公式:
 
通项公式
 
常理告诉我们,按照通项公式向后推出后面的项是解决问题最直接的方法,但是耗时耗力,很不划算。现在请出我们解决这个问题的英雄,其实是一个数学定理:如果一个数列的通项公式是关于自然数 n r 次多项式,那么这个数列是r阶等差数列。(这个好像说得挺晕的)我们把它的思路清理一下,先给大家看一张图:
 
数组拆解实例
 
         这里的原数列是指密码锁上提供的线索,顺藤摸瓜是我们常用的手段。(这里以1,4,9的密码线索作为样例)首先,我们要不断的求数列中前后两项的差,然后用这些差构成一个新的数列。这就得到了1阶等差数列,由此方法得到2阶等差数列,一直到得到r阶等差数列(就像这里的2阶等差数列)。我们出这样的计算方法使得没进行一轮的求差,数列元素的个数就会减少一个,当我们把数列处理为只有一个元素时,我们要的自然数n就出现了,而且它是常数列,由此我们的下一项也就有据可查了。按照图中蓝色箭头所指的方向,我们可以把这里的2阶等差数列的最后面的2加上上一层的最后的元素,从而得到上一层的后一项,依照同样的方法,我们可以推出元数列的后一项。至此,我们就把密码锁解开了。
但是这个方法仅仅适用于r阶等差数列,那么我们如何判断任意给定的一个数列是否为r阶等差数列呢?
这又是一个难于回答的问题,我们如果按照通项公式去推的话,和直接用同项公式去做也就没什么区别了;如果我们假定它是r阶等差数列而直接用上述方法去做的话,工作量也会很大。我进行了多次的数据测试后发现,如果一个数列是由等差数列的元素经过相同的变换构造而成的话,这个数列的后一项就可以用上述方法求解,换而言之,就是r阶等差数列。
关于判断数列是否为r阶等差数列的问题我也是通过大量的数据试验得到的,并没有严格的数学理论支持,我希望看过这篇文章的朋友能帮我找到数学的理论支持。
最后附上我的JAVA源代码:

这个是PasLock.java
/**
 *Name:PasLock.java
 *Author:Richard
 *Date:Apr-17,2006
 *Version:1.0.0.0
 *=================
 *
 */
 
 public class PasLock{
  
  protected long result;
  
 /**
  *construct method
  */
  public PasLock(){
   
   result = 0;
  }
  
 /**
  *
  */
  public long r_cal(long num[]){
   
   int m = num.length;
   
   for(int j=m-1; j>0; j--)
    for(int k=0; k<=j-1; k++)
     num[k] = num[k+1]-num[k];
   
   for(int j=0; j<m; j++)
    result = result+num[j];
   
   return result;
  }
 };
 //==========End Class PasLock==========

这个是PasLockTest.java
/**
 *Name:PasLockTest.java
 *Author:Richard
 *Date:Apr-17,2006
 *Version:1.0.0.0
 *=====================
 *Test the class PasLock
 */
 
 public class PasLockTest{
  
  public static void main(String args[]){
   
   long num[] = {5, 8, 13};
   
   PasLock resultOfLock = new PasLock();
   
   System.out.println("result of lock is " +resultOfLock.r_cal(num));
  }
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值