/** * * 找出四位数的所有吸血鬼数字 * 吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序. * 以两个0结尾的数字是不允许的。 * 例如下列数字都是吸血鬼数字 * 1260=21*60 * 1827=21*87 * 2187=27*81 * ... * 首先想到的一种低效率的做法: 遍历所有四位数, 每生成一个四位数的时候,去判断是否符合。 * @author zz * */ public class XixueguiNum { public static int combine(int i, int j){ return i * 10 + j; } public static void xiXueGuiNum(int m){ String str = m + ""; char[] c = str.toCharArray(); int[] a = new int[c.length]; String[] s = new String[c.length/2]; for(int i = 0; i < c.length; i++){ a[i] = Character.getNumericValue(c[i]); } if(combine(a[0],a[1])*combine(a[2],a[3]) == m) { System.out.println(m + " = " + combine(a[0],a[1]) + " * " + combine(a[2],a[3])); } if(combine(a[0],a[1])*combine(a[3],a[2]) == m){ System.out.println(m + " = " + combine(a[0],a[1]) + " * " + combine(a[3],a[3])); } if(combine(a[0],a[2])*combine(a[1],a[3]) == m){ System.out.println(m + " = " + combine(a[0],a[2]) + " * " + combine(a[1],a[3])); } if(combine(a[0],a[2])*combine(a[3],a[1]) == m) { System.out.println(m + " = " + combine(a[0],a[2]) + " * " + combine(a[3],a[1])); } if(combine(a[0],a[3])*combine(a[1],a[2]) == m) { System.out.println(m + " = " + combine(a[0],a[3]) + " * " + combine(a[1],a[2])); } if(combine(a[0],a[3])*combine(a[2],a[1]) == m) { System.out.println(m + " = " + combine(a[0],a[3]) + " * " + combine(a[2],a[1])); } if(combine(a[1],a[0])*combine(a[2],a[3]) == m) { System.out.println(m + " = " + combine(a[1],a[0]) + " * " + combine(a[2],a[3])); } if(combine(a[1],a[0])*combine(a[3],a[2]) == m) { System.out.println(m + " = " + combine(a[1],a[0]) + " * " + combine(a[3],a[2])); } if(combine(a[1],a[2])*combine(a[0],a[3]) == m) { System.out.println(m + " = " + combine(a[1],a[2]) + " * " + combine(a[0],a[3])); } if(combine(a[1],a[2])*combine(a[3],a[0]) == m) { System.out.println(m + " = " + combine(a[1],a[2]) + " * " + combine(a[3],a[0])); } if(combine(a[1],a[3])*combine(a[0],a[2]) == m) { System.out.println(m + " = " + combine(a[1],a[3]) + " * " + combine(a[0],a[2])); } if(combine(a[1],a[3])*combine(a[2],a[0]) == m) { System.out.println(m + " = " + combine(a[1],a[3]) + " * " + combine(a[2],a[0])); } if(combine(a[2],a[0])*combine(a[3],a[1]) == m){ System.out.println(m + " = " + combine(a[2],a[0]) + " * " + combine(a[3],a[1])); } if(combine(a[2],a[1])*combine(a[3],a[0]) == m) { System.out.println(m + " = " + combine(a[2],a[1]) + " * " + combine(a[3],a[0])); } if(combine(a[3],a[0])*combine(a[2],a[1]) == m) { System.out.println(m + " = " + combine(a[3],a[0]) + " * " + combine(a[2],a[1])); } if(combine(a[3],a[1])*combine(a[2],a[0]) == m) { System.out.println(m + " = " + combine(a[3],a[1]) + " * " + combine(a[2],a[0])); } } public static void main(String[] args) { for(int i = 1000; i < 10000; i++){ xiXueGuiNum(i); } } }
代码调试后有个小问题,6880 = 86 * 80 = 80 * 86 (这里的8分属第一第二位,重复判断输出了两次结果。)
这种代码效率很低,在网上搜到了一种解题思想是逆向求两位数相乘的结果是否等于四位数。中间的关键在于给字符串排序,避免遗漏。代码如下:
public class XixueguiNum1 { public static void xiXueGuiNum(){ String[] str1 = null; String[] str2 = null; for(int i=10; i<100; i++){ for(int j=i+1; j<100; j++){ int m = i * j; if(m < 1000 || m > 9999) continue; str1 = String.valueOf(m).split(""); str2 = (String.valueOf(i)+String.valueOf(j)).split(""); java.util.Arrays.sort(str1); java.util.Arrays.sort(str2); if(java.util.Arrays.equals(str1, str2)){ System.out.println(m + " = " + i + " * " + j); } } } } public static void main(String[] args) { // TODO Auto-generated method stub xiXueGuiNum(); } }