其中 rom args 等于 偶数 air 修改 可能
首先解释一下吸血鬼数字:吸血鬼数字是指位数为偶数的数字,可由一对数字相乘而得到,这对数字各包含乘积的一半位数的数字,以两个0结尾的数字是不允许的。
四位数吸血鬼数字示例:1260=21*60,1827=21*87,2187=27*81……
先列出结果:一共7个:1260=21*60,1395=15*93,1435=41*35,1530=51*30,1827=87*21,2187=27*81,6880=86*80
方法一:
本方法是《Thinking in Java》的官方答案,由于所处章节很靠前,所以采用的遍历四位数方法,正向思维,即先有四位数,再拆分,四个数字组合相乘,若乘积与原数相等,则输出,并计算为一个吸血鬼数字。
方法二:
本方法是对方法一的改进,跳过了一些数字(如1100这样末尾两个0的,如1010、1001这样明显不可能是吸血鬼数字的数字),并且避免了出现重复的可能性,但是效率仍然很低,需要判断104942次。
public class SearchforVampireNumbersLJ { public static int count = 0;// 记录一共有多少个吸血鬼数字 public static int k=0;//记录调用判断多少次 public static void main(String[] args) { for (int i = 1001; i < 10000; i++) { // 如果数字是像1100这种末尾至少有2个0的,则跳过 if (i % 100 == 0) { continue; } // 获得数字四个数值位上的数字,这里我们假定四位数表示为abcd int a = i / 1000; int b = (i - a * 1000) / 100; int c = (i - a * 1000 - b * 100) / 10; int d = i - a * 1000 - b * 100 - c * 10; // 判断四个位置上是否有两个0存在的情况,如1010,并跳过这些数,由于千位不可能为0,因此只需要判断另外三位是否有2个0的情况 // 当3个数中有2个0时,必然存在“3个数之和等于其中某一个数”,以此作为判断依据,而后两位为0的也已经排除,其实只需要判断如1001,和1010这种情况即可 if (b + c + d == c || b + c + d == d) { continue; } // 排除掉各种情况后,可以开始真正的吸血鬼数字筛选了 // 那么一共有12种情况:abcd,abdc,acbd,acdb,adbc,adcb,bacd,badc,bcda,bdca,cadb,cbda if (search(i, a, b, c, d)) { } else if (search(i, a, b, d, c)) { } else if (search(i, a, c, b, d)) { } else if (search(i, a, c, d, b)) { } else if (search(i, a, d, b, c)) { } else if (search(i, a, d, c, b)) { } else if (search(i, b, a, c, d)) { } else if (search(i, b, a, d, c)) { } else if (search(i, b, c, d, a)) { } else if (search(i, b, d, c, a)) { } else if (search(i, c, a, d, b)) { } else if (search(i, c, b, d, a)) { } } System.out.println("四位数的吸血鬼数字一共有" + count + "个。"); System.out.println("一共调用判断次数为" + k); }
//判断是否满足条件 static boolean search(int i, int a, int b, int c, int d) { k++; if ((a * 10 + b) * (c * 10 + d) == i) { searchfor(i,a,b,c,d);//如果满足条件,则打印结果 return true; }else{ return false; } }
//满足条件即打印,并且统计个数 static void searchfor(int i, int a, int b, int c, int d) { count++; System.out.println(i + "=" + (a * 10 + b) + "*" + (c * 10 + d)); }}
方法三:
以下是网上找的代码,该算法采用逆向思维,4位数字的吸血鬼数字只能拆分成两个2位数,因此遍历所有两个两位数相乘的情况,除去不符合的情况不用判断,其他挨个判断即可。
public class SearchforVampireFromInternet { /** * 代码来自网络,略作修改并添加了注释 * 该算法只需要执行3721次 */ public static void main(String[] args) { String[] targetNum = null; String[] gunNum=null; //目标数字和枪数字(即对比数字) int sum = 0; //吸血鬼数字的总个数 int count=0; //有效判断次数,那些乘积不是4位数的就排除了 for (int i = 10; i < 100; i++) { for (int j = i+1; j < 100; j++) { //没有哪个两位数满足ab*ab=abab(不信可以编程验证),所以这里j从i+1开始就可以了 int i_target = i * j; if (i_target < 1000 || i_target > 9999) continue; // 积不是4位数则跳过 count++; targetNum = String.valueOf(i_target).split(""); //将其转换为一个字符串数组 gunNum = (String.valueOf(i) + String.valueOf(j)).split(""); java.util.Arrays.sort(targetNum); //升序排列,因为只有排列了再比较才能保证不遗漏abcd=ba*dc这样的情况 java.util.Arrays.sort(gunNum); if (java.util.Arrays.equals(targetNum, gunNum)) { // 排序后比较,为真则找到一组 sum++; System.out.println("第" + sum + "个: " + i_target+"="+i + "*" + j); } } } System.out.println("共进行了"+count+"次判断,找到" + sum + "个吸血鬼数字。"); } }
Thinking In Java 里面吸血鬼数字题
来源: http://www.bubuko.com/infodetail-2105940.html