首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

关于吸血鬼数字,该如何处理

2012-04-26 
关于吸血鬼数字A vampire number has an even number of digits and is formed by multiplying a pair of

关于吸血鬼数字
A vampire number has an even number of digits and is formed by multiplying a pair of numbers containing half the number of digits of the result. The digits are taken from the original number in any order. Pairs of trailing zeroes are not allowed. Examples include:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
Write a program that finds all the 4-digit vampire numbers. (Suggested by Dan Forhan.)

Java code
import java.util.*;public class Vampire {    public static void main(String [] args){        int [] a = new int [4];   //数组a中存放四位数的每位数字        int [][] b = new int [4][3];  //存放的四个数字可以12个两位数,以二维数组形式存放        for(int i = 1000; i <10000; i++){            int count = 0;   //count 用于判断条件            int nu = i;   //临时变量,代替当前i值            for(int j = 0 ; j < 4; j++){   //取出四位数中的每位数字,存放在数组a中                a[j] = nu % 10;   //取余,即取末尾数字                nu = nu / 10;     //nu迭代,略去最后一位数字            }            //将取出来的四位数字,组合成两位数,存放在二位数组中            //比如四位数字a,b,c,d,数组{a,b,c,d},组成的12个两位数是            // ab,ba,ca,da            // ac,bc,cb,db            // ad,bd,cd,dc            for(int j = 0; j < 4; j++){                int m = 0;                for(int k = 0; k < 3 ; k++){                        if(m == j) //每个数字不能同自己组合,比如没有aa,bb,cc,dd                            m++;   //碰到自身,m++,跳过自己与自己组合的可能性                        if( m==4 ) //当 m=j=3时,即到数字d时,通过上一步m++变为4,这时m已经越界了                            break; //用break语句跳出循环,防止越界,因为 a[4] 不存在                        b[j][k] = a[j]*10 + a[m];                        m++; // m++,b[0][3]跳到b[1][0],b[1][3]跳到b[2][0],b[2][3]跳到b[3][0]                    }                }            //鉴于二维数组的操作性,将二维数组里的内容赋到一维数组中            int n = 0;            int [] c = new int [12]; //实例一维数组 c[12]                for(int k = 0; k < 4; k++){                    for(int l = 0 ; l < 3; l++){                        c[n] = b[k][l]; //将二维数组内容逐个赋给一维数组                        n++;                    }                }            Arrays.sort(c); //将数组排序,升序            Arrays.sort(a); //将数组排序,升序            //判别吸血鬼数字            for(int j = 1 ; j < 12 ;j++){  //c[j] 从第二项开始                for(int k = 0; k < j ; k++){ //c[k] 从第一项开始,避免重复,k<j                    if( i == c[j]*c[k]){   //第一个满足条件,i==c[j]*c[k]                        int cj = c[j];    //临时变量cj 代替c[j]                        int ck = c[k];    //临时变量ck 代替c[k]                        int [] aa = new int [4]; //实例数组aa,用于存放c[j],c[k]包含的                                                 // 四个数字,用于同数组a比较                        aa[0] = cj % 10; //取c[j]个位数字                        cj = cj / 10;    //                        aa[1] = cj;      //取c[j]十位数字                                            aa[2] = ck % 10; //取c[k]个位数字                        ck = ck /10;     //                        aa[3] = ck;      //取c[k]十位数字                         Arrays.sort(aa); //对数组aa排序,升序,便于同数组a比较                        if(Arrays.equals(a, aa)){  // 比较数组a同aa的内容是否相同                            if(!(c[j] % 10 == 0 && c[k] % 10 == 0)){ //剔除两个数都是以0结尾的                                count++; //若找到count++                                System.out.println("vampire number : " + i +                                        "\nmultiplying by : " + c[j] + " and " + c[k]);                            }                        }                    }                }            }            if(count > 0)                System.out.println();        }    }}


运行结果郁闷

run:
vampire number : 1260
multiplying by : 60 and 21

vampire number : 1395
multiplying by : 93 and 15

vampire number : 1435
multiplying by : 41 and 35

vampire number : 1530
multiplying by : 51 and 30

vampire number : 1827
multiplying by : 87 and 21

vampire number : 2187


multiplying by : 81 and 27

vampire number : 6880
multiplying by : 86 and 80
vampire number : 6880
multiplying by : 86 and 80
vampire number : 6880
multiplying by : 86 and 80
vampire number : 6880
multiplying by : 86 and 80


好像过不了6880,怎么会有四个6880输出呢!

[解决办法]
看下 这个源代码吧 
吸血鬼数字
http://blog.csdn.net/java_cxrs/archive/2008/11/13/3286305.aspx
[解决办法]
你没考虑数字重复问题呃
if(Arrays.equals(a, aa)){ // 比较数组a同aa的内容是否相同
if(!(c[j] % 10 == 0 && c[k] % 10 == 0)){ //剔除两个数都是以0结尾的
count++; //若找到count++
System.out.println("vampire number : " + i +
"\nmultiplying by : " + c[j] + " and " + c[k]);
break lable; //找到一个就ok了 lable就做最上面循环的标签就好了
}
}

[解决办法]
过不了6880,是因为后面确实再没有吸血鬼数字了
有四个6880,是因为两个8,既68 跟 68 是不一样的(8分别是第二个8和第三个8)。 可以通过程序控制。
如果有四个数字相同的吸血贵数字的话,你的程序,就会输出12组数据啦~~~
[解决办法]
看看java2000_net写的吸血鬼数字的程序,这是地址http://blog.csdn.net/java2000_net/archive/2009/01/23/3851203.aspx ,效率很高的
[解决办法]
这是java2000_net写的程序
贴出来大家看下

Java code
 
import java.util.Arrays; 
/** 
* 吸血鬼数字,高效率版本. <br> 
* 一个4位数字,可以拆分2个2位数数字的乘积,顺序不限。 <br> 
* 比如 1395 =15 * 93 

* @author 老紫竹(laozizhu.com) 
*/ 
public class Vampire { 
public static void main(String[] arg) { 
  String[] ar_str1, ar_str2; 
  int sum = 0; 
  int from; 
  int to; 
  int i_val; 
  int count = 0; 
  // 双重循环穷举 
  for (int i = 10; i < 100; i++) { 
  // j=i+1避免重复 
  from = Math.max(1000 / i, i + 1); 
  to = Math.min(10000 / i, 100); 
  for (int j = from; j < to; j++) { 
    i_val = i * j; 
    // 下面的这个代码,我个人并不知道为什么,汗颜 
    if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) { 
    continue; 
    } 
    count++; 
    ar_str1 = String.valueOf(i_val).split(""); 
    ar_str2 = (String.valueOf(i) + String.valueOf(j)).split(""); 
    Arrays.sort(ar_str1); 
    Arrays.sort(ar_str2); 
    if (Arrays.equals(ar_str1, ar_str2)) {// 排序后比较,为真则找到一组 
    sum++; 
    System.out.println("第" + sum + "组: " + i + "*" + j + "=" + i_val); 
    } 
  } 
  } 
  System.out.println("共找到" + sum + "组吸血鬼数"); 
  System.out.println(count); 





运行结果

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





view plaincopy to clipboardprint?
// 下面的这个代码,我个人并不知道为什么,汗颜
if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) {


continue;
}


假设val = 1000a + 100b + 10c + d, 因为满足val = x * y, 则有x = 10a + b, y = 10c + d
则val - x - y = 990a + 99b + 9c = 9 * (110a + 11b + c), 所以val - x - y能被9整除。
所以满足该条件的数字必定能被9整除,所以可以直接过滤其他数字。 

我准许做一下
x*y = val = 1000a + 100b + 10c + d;
我们假设
x = 10a + b, y = 10c + d

x*y-x-y 
= val - x-y 
= (1000a + 100b + 10c + d) - (10a+b) - (10c +d) = 990a + 99b + 9c 
= 9 * (110a + 11b + c);

对于别的组合可能性,结果一样,比如
x=10c+a; y=10d+b;
x*y-x-y 
= val - x-y 
= (1000a + 100b + 10c + d) - (10c+a) - (10d +b) = 999a + 99b -9d
= 9 * (110a + 11b -d);

当然也能被9整除了

热点排行