21亿以内的自守数--Java求解

    xiaoxiao2023-11-24  162

    21亿以内的自守数–Java求解

    为什么是21亿以内?

    java中long最大数是 9223372036854775807,开方大约是30亿,那我们就求21亿以内的自守数,防止在计算过程中出现溢出的现象。作者初学java,就不去求解更大范围的自守数了。

    什么是自守数—这里就不多赘述了。

    自守数是指某个数的平方的末尾几位数等于这个数的数。

    直接贴出答案

    0 1 5 6 25 76 376 625 9376 90625 109376 890625 2890625 7109376 12890625 87109376 212890625 787109376已验证 1787109376已验证 之前在网上找结果,想验证自己求10000以内自守数是不是正确,到处找不到答案。欢迎大家来验证。

    代码:

    public static void main(String[] args) { for (int i = 0; i < 2100000000; i++) //i不要超过21亿, { long lng = (long)i * i; //i平方是long类型,不会超过long最大,不会溢出(30亿会溢出long类型) long mod = lng % getUp(i); if (i == mod) //i会自动提升为long作比较 { System.out.println(i); } } //验证1787109376 // long lng = (long)1787109376 * 1787109376; // System.out.println(lng);//3193759921787109376 } //方法,输入int n ,返回它的上级(最大情况100亿,所以使用long) //此方法为了求得一个数的上一级别数,比如传入一个两位数(如43),返回100。2566返回10000,一次类推 //该方法方便main中“求末尾数”。 public static long getUp(int n) { long d = 1; //容器,初始为1.每次n除以10,d都会增加10倍,n==0时,d就是10,100,1000,.....类推 while (n != 0) { n /= 10; d *= 10; } return d; }

    关于运行时间,能不能更优化?

    上述代码运行时间挺久,大概10秒(没验证具体时间,有兴趣可以自己验证,和简单,只要3行代码)

    如何提高效率呢?我们根据运行结果,查找规律。发现结果后3位不是625就是376.具体原因涉及到数学方面,我也不懂。 我们可以在循环体中加入一定条件,先判断i是不是625 或者 376 结尾?提高代码效率。

    int m = i % 1000; if (m != 625 && m != 376) { continue; }

    当然这次运行结果会不显示前面的几个自守数,但运行时间确实很短。其实按照这个思路,还能更优化,将i分组,就能在显示全部结果的情况下,时间再次缩短。可以自己尝试。

    最新回复(0)