zoukankan      html  css  js  c++  java
  • 找出"吸血鬼数"(Java)

    吸血鬼数是指位数为偶数的数字,可以由一 对数字相乘而得到,而这对数字各包含乘积的一半 位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是 “吸血鬼”数字:
    1260=21 * 60
    1827=21 * 87
    2187= 27 * 81

    那么,开始

    由于判断四位数是否能分解为两个两位数的乘积,比判断两位数的乘积所得四位数的,要麻烦得多,因此思路为后者。

    import java.util.ArrayList;
    import java.util.Arrays;
    
    /**
     *     先从1001开始到9999开始判断,是否能分解为两个二位数,如果可以,二维数是否包含所有四个数字
     *     把四位数分解成二位数乘积过于麻烦,而且一个四位数可能存在多种分解方式,加大了设计的难度
     *     但是反过来,二位数乘以二位数简单得多,此时再去判断即可
     *     将积分解成四个数位,存入数组。两个乘数分别分解成两个数位,存入一个数组
     *     将两个数组排序,按照下标逐个比较,如果两个数组相同,返回true
     * @author zhaoke
     *
     */
    public class Vampire {
    
        //冒泡排序法
        public void sort(int[] array) {
            for (int i = 0; i < array.length-1; i++) {
                for (int j = i+1; j < array.length; j++) {
                    if (array[i] > array[j]) {
                        //交换两个数的位置
                        array[i] = array[i] - array[j];
                        array[j] = array[i] + array[j];
                        array[i] = array[j] - array[i];
                    }
                }
            }
        }
        
        /**
         * 判断四位数分解后的数位(存在数组里),是否恰好包含两个乘积因子的所有数位
         * 为了简单起见,方法是先排序,然后比较两个数组是否相同
         */
        public boolean check(int[] digits, int num1, int num2) {
            this.sort(digits);
    //        System.out.println(Arrays.toString(digits));
            
            int[] factors = new int[4];
            //分离第一个乘数的两个数位
            int[] numArray = this.divideNumber(num1);
            for (int i = 0; i < 2; i++) {
                factors[i] = numArray[i];
            }
            //分离第二个乘数的两个数位
            numArray = this.divideNumber(num2);
            for (int i = 2; i < 4; i++) {
                factors[i] = numArray[i-2];
            }
            this.sort(factors);
    //        System.out.println(Arrays.toString(factors));
            for (int i = 0; i < digits.length; i++) {
                if (digits[i] != factors[i]) {
                    return false;
                }
            }
            return true;
        }
        
        public int[] divideNumber(int number) {
            int[] digits = new int[2];
            digits[0] = number/10;
            digits[1] = number - 10*(number/10);
            return digits;
        }
        
        /**
         * 获得每个位的数字
         */
        public int[] divideArray(int number) {
            int[] digits = new int[4];
            int factor = 1000;
            for (int i = 0; i < digits.length; i++) {
                digits[i] = number/factor;
                number -= digits[i] * factor;
                factor /= 10;
            }
            return digits;
        }
        ArrayList<Integer> result = new ArrayList<Integer>();
    
        /**
         * 10*99小于1000,因此从11开始循环
         */
        public void start() {
            int count = 0; //计数器而已
            for (int i = 11; i < 100; i++) {
                for (int j = 11; j < 100; j++) {
                    if (i*j <1000)
                        continue;
                    if (i*j%100==0) {
                        //根据题目,如果最后两位是0,也不可
                        continue;
                    }
                    int[] digits = divideArray(i*j);
                    if (this.check(digits, i, j)) {
                        if (this.result.contains(i*j))
                            continue;
                        this.result.add(i*j);
                        System.out.printf("第%d个吸血鬼数: %d = %d x %d 
    ",++count,i*j,i,j);
                    }
                }
            }
        }
        
        public static void main(String[] args) {
            Vampire v = new Vampire();
            v.start();
        }
    
    }

    结果如下:

    第1个吸血鬼数: 1395 = 15 x 93 
    第2个吸血鬼数: 1260 = 21 x 60 
    第3个吸血鬼数: 1827 = 21 x 87 
    第4个吸血鬼数: 2187 = 27 x 81 
    第5个吸血鬼数: 1530 = 30 x 51 
    第6个吸血鬼数: 1435 = 35 x 41 
    第7个吸血鬼数: 6880 = 80 x 86 
    

    总结:逆向思维,模块化设计

  • 相关阅读:
    [na]wac无线控制器集中转发部署的几种情况
    [na]windows2008-AD域的安装
    [na]数据链路层&网络层协议小结截图版
    [na]tcp&udp层各协议小结
    [na]交换机接口文档
    [na]二层sw数据交换
    [na]wireshark排查打印机问题
    [na]ip包格式
    [na]ping提示&各系统默认的TTL值
    【VS开发】C++异常处理操作
  • 原文地址:https://www.cnblogs.com/zhaoke271828/p/12581051.html
Copyright © 2011-2022 走看看