日期:2014-05-20  浏览次数:20718 次

JAVA实现的吸血鬼数字算法,高效率版本(同时求助算法高人解惑)
关于吸血鬼数字的解释我就不写了,原文在我的博客里:
http://blog.csdn.net/java2000_net/archive/2009/01/23/3851203.aspx

希望能解决里面的关键代码
Java code
        // 下面的这个代码,我个人并不知道为什么,汗颜
        if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) {
          continue;
        }




------解决方案--------------------
吸血鬼算法得出的数字不能是两个00结尾的
所以i_val % 100 == 0就直接continue了
至于(i_val - i - j) % 9 != 0的话会导致什么样的数字就不清楚了(数学不好-_-!),一时间还找不到数学系的同学问问(都回家了。。。)
期待楼下解答
------解决方案--------------------
abcd = 1000a+100b+10c-d
任意的2位组合,如ac,db, 表示为10a+c,10d+b
则abcd - ac-db = 990a+99b+9c-9d 
这个数肯定是9的倍数,
对于其他的2位组合,也成立
所以,对于满足条件的吸血鬼数字,(i_val - i - j) % 9 != 0 肯定成立
不满足这个条件的,则不是吸血贵数字

------解决方案--------------------
一、吸血鬼数字的两个因子不能同时以0结尾,故用条件i_val % 100 == 0 先过滤一次。
二、任何4位数i_val都可以表示为1000a+100b+10c+d
如果其是吸血鬼数字,其两个因子是i和j,那么i+j只能有以下六种情况:
1.(i+j)=10a+b+10c+d
2.(i+j)=10a+10b+c+d
3.(i+j)=10a+b+c+10d
4.(i+j)=a+10b+c+10d
5.(i+j)=a+10b+10c+d
6.(i+j)=a+b+10c+10d
所以无论上述的哪种情况下i_val-(i+j)都一定能被9整除,故不满足这个条件的一定不是吸血鬼数字,所以通过条件(i_val - i - j) % 9 != 0再过滤一次。

以上是个人的理解,不知道对错,仅供参考,班门弄斧了:)

------解决方案--------------------
假设val = 1000a + 100b + 10c + d, 拆分成val = x * y

而x是a、b、c、d中两个的线性组合,y是另两个的线性组合,系数分别是10和1
则val-x-y
=val-m1*a-m2*b-m3*c-m4*d //m1\m2\m3\m4 是10或者是1
=1000a + 100b + 10c + d-m1*a-m2*b-m3*c-m4*d
=(1000-m1)a+(100-m2)b+(10-m3)c+(1-m4)d

1000-m1等900或者999,能被9整除
100-m2等90或者99,能被9整除
10-m3等0或者9,能被9整除
1-m4等-9或者0,能被9整除

所以(1000-m1)a+(100-m2)b+(10-m3)c+(1-m4)d能被9整除
得到val-x-y能被9整除