zoukankan      html  css  js  c++  java
  • 算法题练习(完数、是否合数、水仙花数)

    【程序9】题目:一个数如果恰好等于它的真因子之和,这个数就称为“完数”。例如6=1+2+3。编程找出1000以内的所有完数。

      @Test
        public void test07() {
            int s;
            for (int i = 1; i < 1000; i++) {
                s = 0;
                /**
                 * 1 一定是所有数的真因子;
                 * 因为是真因子,所以判断因子的这一步要小于i
                 */
                for (int j = 1; j < i; j++) {
                    if (i % j == 0) {
                        s = s + j;
                    }
                    
                }
                if (s == i) {
                    System.out.println("1000以内的完数有:" + i);
                }
            }
        }

    得到的输出结果是:

    1000以内的完数有:6
    1000以内的完数有:28
    1000以内的完数有:496

    优化:利用直观的想法。

    其实寻找 i 的真因子,我们使用的是循环,从1到 i-1 ,其实这里只需要判断到 i/2  就可以了。这是因为,在正数 i 的所有真因子中, 最大的真因子肯定不会超过 i / 2 。

    这样可以减少内层循环的次数。

    分析:如果这个数是一个奇数,例如 23:

    23/2=12,判断到 12 不是 23 的真因子,就没有必要去判断 13 、 14 、15 直到 22 是不是 23 的真因子。

    如果这个数是偶数 例如 24 :

    24/2=12,同样地,判断到 12 是 24 的真因子,也没有必要去判断 13 、 14 、15 直到 22 是不是 23 的真因子。

    为此,我们的内层循环,可以这样优化:

    【程序2】程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。

      @Test
        public void test08(){
            System.out.println(isZhiShu(7));
        }
        
        public boolean isZhiShu(int x){
            for(int i=2;i<=Math.sqrt(x);i++){
                if(x%i==0){
                    return false;
                }
            }
            return true;
        }

    分析:这里要用到一个数学结论。如果一个数是合数,那么它必有一个素因子小于等于它的平方根。证明如下。

    设 n=pq 是合数,且 1<p<q ,则 p^2<pq=n ,则 p<Math.sqrt(n) 。(证完)

    关于整除的理论,可以参考下面的文章:

    初等数论 第一章 整除理论_百度文库
    http://wenku.baidu.com/link?url=oKZ4jRKHrPAGocTc15M1A5uFRJmI4CwgX6sRZeKs-c_wwNG_wWV6bxoRVzzSFeltM1moFy4ihocif9UL2zBD4vTuoMpxQZcqIYfeuxLgORu

    【程序3】题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各个位数字的立方和等于该数本身。例如:153是一个“水仙花数”,因为153=1的三次方+5的三次方+3的三次方。

    程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。

        @Test
        public void test09(){
            int x,y,z;// 个位、十位、百位
            for(int i =100;i<1000;i++){
                x = i % 10; // 个位
                z = i / 100 ; // 百位
                // y = (i - 100*z - x)/10; // 这一步还可以优化
                y = (i%100)/10;
                if(i== (Math.pow(x, 3) + Math.pow(y, 3) + Math.pow(z, 3))){
                    System.out.println("1000 以内的水仙花数有:" + i);
                }
            }
        }
        
  • 相关阅读:
    参数解包*args
    Gym 101142C CodeCoder vs TopForces(搜索)
    CCCC 连续因子
    CCCC 红色警报
    CCCC 正整数A+B
    POJ 3669 Meteor Shower(bfs)
    【USACO1.5】解题报告
    【USACO1.5】解题报告
    【USACO1.4】解题报告
    【USACO1.4】解题报告
  • 原文地址:https://www.cnblogs.com/liweiwei1419/p/4471754.html
Copyright © 2011-2022 走看看