吸血鬼数字的算法的问题

yazhouren 2007-10-31 12:37:24
大家帮帮忙,java thinking 中的一道题,看看怎么解:
吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,而对数字各包含乘积的一半数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,列如:
1260=21*60;
1827=21*87;
2187=27*81;
请写出一个程序,找出所有的4位吸血鬼数字。
小弟是才学java不久,希望大家帮助。
...全文
491 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
xueyicheneng 2012-05-25
  • 打赏
  • 举报
回复
上面 9 楼的 版本
xueyicheneng 2012-05-25
  • 打赏
  • 举报
回复
for(int r=0;r<4;r++){
for(int t=0;t<3;t++){
if(na[t]<na[t+1]){
int nt = na[t];
na[t] = na[t+1];
na[t+1] = nt;
}
if(nb[t]<nb[t+1]){
int nr = nb[t];
nb[t] = nb[t+1];
nb[t+1] = nr;
}
}
}

我想知道, 这段是干嘛用的
tea_pig 2011-07-08
  • 打赏
  • 举报
回复
倒序一下就可以解决重复问题了.


/**
* Create by TPig
* Since 2011-7-6下午05:55:56
*/
package com.xiaoxindd.thinkjava.part4;

import java.util.Arrays;

/**
* 类说明:
*
* @Author Create by TPig Since 2011-7-6 下午05:55:56
*/
public class Demo4_1 {

public static void main(String[] args) {
int a = 10;
while (a < 100) {
a++;
int b = 99;
while (b > 10 && b > a) {
b--;
int sum = a * b;
if(split(sum).length != 4) {
// 乘积不等于4位
continue;
}
if(sum % 100 == 0) {
continue;
}
int[] aSplit = split(a);
int[] bSplit = split(b);
int[] sumSplit = split(sum);
int i = compareCount(sumSplit, aSplit);
if(i != 2) {
continue;
}
i = compareCount(sumSplit, bSplit);
if(i != 2) {
continue;
}
System.out.println(a + " " + b + " " + sum);
}
}
}

/**
* 方法说明:分割一个整数,生成数组
*
* @param num
* @return
* @Author Create by TPig Since 2011-7-7 下午02:00:32
*/
private static int[] split(int num) {
int[] it = new int[1];
int i = 0;
while (num != 0) {
if(i == it.length) {
it = Arrays.copyOf(it, it.length + 1);
}
it[i++] = num % 10;
num /= 10;
}
return it;
}

/**
* 方法说明:比较两个数组是否有相同数字
*
* @param sum
* @param b
* @return
* @Author Create by TPig Since 2011-7-7 下午01:49:10
*/
private static int compareCount(int[] sum, int[] b) {
int i = 0;
for (int j = 0; j < sum.length; j++) {
for (int m = 0; m < b.length; m++) {
if(sum[j] == b[m]) {
sum[j] = -1;
b[m] = -2;
i++;
break;
}
}
}

return i;
}
}

complexgg 2011-07-07
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 huangshaojun 的回复:]
转换成字符串,拆开数据,用循环任意组合,用一个boolean类型变量做标记,可以除去相同的情况。


Java code


class BloodGost
{
private static void getBloodGostNumber(int number)
{
String strnum = "" + number;
in……
[/Quote]

the 'for circle' is too much .less than two circles is better
tea_pig 2011-07-07
  • 打赏
  • 举报
回复

/**
* Create by TPig
* Since 2011-7-6下午05:55:56
*/
package com.xiaoxindd.thinkjava.part4;

import java.util.Arrays;

/**
* 类说明:
*
* @Author Create by TPig Since 2011-7-6 下午05:55:56
*/
public class Demo4_1 {

public static void main(String[] args) {
int a = 10;
int b = 10;
int sum = a * b;
while (a < 100 && sum < 10000) {
a++;
b = 10;
while (b < 100) {
b++;
sum = a * b;
if(split(sum).length != 4) {
// 乘积不等于4位
continue;
}
if(sum % 100 == 0) {
continue;
}
int[] aSplit = split(a);
int[] bSplit = split(b);
int[] sumSplit = split(sum);
int i = compareCount(sumSplit, aSplit);
if(i != 2) {
continue;
}
i = compareCount(sumSplit, bSplit);
if(i != 2) {
continue;
}
System.out.println(a + " " + b + " " + sum);
}
}
}

/**
* 方法说明:分割一个整数,生成数组
*
* @param num
* @return
* @Author Create by TPig Since 2011-7-7 下午02:00:32
*/
private static int[] split(int num) {
int[] it = new int[1];
int i = 0;
while (num != 0) {
if(i == it.length) {
it = Arrays.copyOf(it, it.length + 1);
}
it[i++] = num % 10;
num /= 10;
}
return it;
}

/**
* 方法说明:比较两个数组是否有相同数字
*
* @param sum
* @param b
* @return
* @Author Create by TPig Since 2011-7-7 下午01:49:10
*/
private static int compareCount(int[] sum, int[] b) {
int i = 0;
for (int j = 0; j < sum.length; j++) {
for (int m = 0; m < b.length; m++) {
if(sum[j] == b[m]) {
sum[j] = -1;
b[m] = -2;
i++;
break;
}
}
}

return i;
}
}




15 93 1395
21 60 1260
21 87 1827
27 81 2187
30 51 1530
35 41 1435
41 35 1435
51 30 1530
60 21 1260
80 86 6880
81 27 2187
86 80 6880
87 21 1827
93 15 1395
robinson00544 2008-07-09
  • 打赏
  • 举报
回复
请问那种是比较不错的方法呢?
yztommyhc 2007-11-07
  • 打赏
  • 举报
回复
public   class   Xixuegui   { 

/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
int a,b,c,d;
for(int k=1001;k <10000;k++){
int q=k;
if(q%100==0)
continue;
a = k / 1000;
b = (k % 1000) / 100;
c = (k % 100) / 10;
d = (k % 10);
if(q==(10*a+b)*(10*c+d) ¦ ¦q==(10*a+b)*(10*d+c) ¦ ¦q==(10*b+a)*(10*c+d) ¦ ¦q==(10*b+a)*(10*d+c) ¦ ¦
q==(10*a+c)*(10*b+d) ¦ ¦q==(10*a+c)*(10*d+b) ¦ ¦q==(10*c+a)*(10*b+d) ¦ ¦q==(10*c+a)*(10*d+b) ¦ ¦
q==(10*a+d)*(10*b+c) ¦ ¦q==(10*a+d)*(10*c+b) ¦ ¦q==(10*d+a)*(10*b+c) ¦ ¦q==(10*d+a)*(10*c+b))
System.out.println(q);


}
}
}


13楼的注意格式
sutdy 2007-11-07
  • 打赏
  • 举报
回复
1楼的算法明了易懂。
zbl0201 2007-11-01
  • 打赏
  • 举报
回复
问下三楼的
1 ar_str2=(String.valueOf(i)+String.valueOf(j)).split(""); 中
split(""); 是什么意思 进行split是为什么是用"";
2为什么进行排序
lhbyjx 2007-11-01
  • 打赏
  • 举报
回复

public class Xixuegui {

/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
int a,b,c,d;
for(int k=1001;k<10000;k++){
int q=k;
if(q%100==0)
continue;
a = k / 1000;
b = (k % 1000) / 100;
c = (k % 100) / 10;
d = (k % 10);
if(q==(10*a+b)*(10*c+d)||q==(10*a+b)*(10*d+c)||q==(10*b+a)*(10*c+d)||q==(10*b+a)*(10*d+c)||
q==(10*a+c)*(10*b+d)||q==(10*a+c)*(10*d+b)||q==(10*c+a)*(10*b+d)||q==(10*c+a)*(10*d+b)||
q==(10*a+d)*(10*b+c)||q==(10*a+d)*(10*c+b)||q==(10*d+a)*(10*b+c)||q==(10*d+a)*(10*c+b))
System.out.println(q);


}
}
}


我刚做的
zbl0201 2007-11-01
  • 打赏
  • 举报
回复
谢谢你的耐心讲解明白了 !!
dyw31415926 2007-11-01
  • 打赏
  • 举报
回复
这几句代码的作用是
校验2个两位数的数字是否跟乘积的数字一样
split("");注意这里不是用" "靠空格分割,而是用""分割

比如 21 * 60 = 1260
则 ar_str2=(String.valueOf(i)+String.valueOf(j)).split("");
得到 String[]是 "" 2 1 6 0

ar_str1=String.valueOf(i_val).split("");
得到 String[] 是 "" 1 2 6 0

经过排序后都为 "" 0 1 2 6
这样,只有两个String[] 相等,就表明数字是一样的,即i=21 j= 60的 0 1 2 6都是从1260中取得的


iimgal 2007-10-31
  • 打赏
  • 举报
回复
public class Test {

public static void main(String[] args){
int i,j;
for(i=10;i<100;i++){
for(j=10;j<100;j++){
int n = i*j;
int n1 = n/1000;
int n2 = n%1000/100;
int n3 = n%1000%100/10;
int n4 = n%1000%100%10;
int i1 = i/10;
int i2 = i%10;
int j1 = j/10;
int j2 = j%10;
if(j2==0&&i2==0){
continue;
}
int [] na = {n1,n2,n3,n4};
int [] nb = {i1,i2,j1,j2};
for(int r=0;r<4;r++){
for(int t=0;t<3;t++){
if(na[t]<na[t+1]){
int nt = na[t];
na[t] = na[t+1];
na[t+1] = nt;
}
if(nb[t]<nb[t+1]){
int nr = nb[t];
nb[t] = nb[t+1];
nb[t+1] = nr;
}
}
}
if(na[0]==nb[0]&&na[1]==nb[1]&&na[2]==nb[2]&&na[3]==nb[3]){
System.out.println(n+"="+i+"*"+j);
}
}
}
}
}


1395=15*93
1260=21*60
1827=21*87
2187=27*81
1530=30*51
1435=35*41
1435=41*35
1530=51*30
1260=60*21
6880=80*86
2187=81*27
6880=86*80
1827=87*21
1395=93*15

笨方法14组
yazhouren 2007-10-31
  • 打赏
  • 举报
回复
谢谢各位了,辛苦了
胡矣 2007-10-31
  • 打赏
  • 举报
回复
mark
zbl0201 2007-10-31
  • 打赏
  • 举报
回复
呵呵 学习了
huangshaojun 2007-10-31
  • 打赏
  • 举报
回复
转换成字符串,拆开数据,用循环任意组合,用一个boolean类型变量做标记,可以除去相同的情况。


class BloodGost
{
private static void getBloodGostNumber(int number)
{
String strnum = "" + number;
int [] subnum = new int[4];
for (int t = 0;t < 4 ;t++ )
{
subnum[t] = Integer.parseInt(strnum.substring(t,t+1));
}
boolean mark = false;
for (int i = 0;i < 4 ;i++ )
{
for (int j = 0;j < 4 ;j++ )
{
if (i!=j)
{
for (int n = 0;n < 4 ;n++ )
{
if (i!=n&&j!=n)
{
for (int m = 0;m < 4 ;m++ )
{
if (i!=m&&j!=m&&n!=m)
{
mark = PrintBloodGostNumber(number,10*subnum[i]+subnum[j],10*subnum[n]+subnum[m]);
if (mark)
{
break;
}
}
}
if (mark)
{
break;
}
}
}
if (mark)
{
break;
}
}
}
if (mark)
{
break;
}
}
}
private static boolean PrintBloodGostNumber(int number,int num1,int num2)
{
if (number == num1 * num2)
{
System.out.println(num1 + " * " + num2 + " = " + number);
}
return (number == num1 * num2);
}
public static void main(String[] args)
{
for (int i = 1000;i < 9999 ;i++ )
{
getBloodGostNumber(i);
}
}
}


输出结果:
21 * 60 = 1260
15 * 93 = 1395
41 * 35 = 1435
51 * 30 = 1530
87 * 21 = 1827
27 * 81 = 2187
86 * 80 = 6880
liuguangyi12 2007-10-31
  • 打赏
  • 举报
回复
public static void main(String args[]) {
for(int i=1;i<=99;i++){
for(int j=1;j<=99;j++){
int count = i*j;
if(count%100!=0&&count>1000&&count<=9999){
String strCount = count+"";
String strI = i+"";
String strJ = j+"";
if(isResult(strCount, strI, strJ)){
System.out.println(""+i+"*"+j+"="+count);
}
}
}
}
}

public static boolean isResult(String count,String i,String j){
boolean result = true;
for(int t=0;t<i.length();t++){
String tt = i.substring(t,t+1);
if(count.lastIndexOf(tt)<0){
return false;
}
count = count.substring(0,count.lastIndexOf(tt))+count.substring(count.lastIndexOf(tt)+1);
}
for(int t=0;t<j.length();t++){
String tt = j.substring(t,t+1);
if(count.lastIndexOf(tt)<0){
return false;
}
count = count.substring(0,count.lastIndexOf(tt))+count.substring(count.lastIndexOf(tt)+1);
}
return result;
}



结果是:
15*93=1395
21*60=1260
21*87=1827
27*81=2187
30*51=1530
35*41=1435
41*35=1435
51*30=1530
60*21=1260
80*86=6880
81*27=2187
86*80=6880
87*21=1827
93*15=1395
dyw31415926 2007-10-31
  • 打赏
  • 举报
回复
反过来想,
不从考虑某个数(1001到9999)是不是吸血鬼数,
而是遍历2位数相乘,看是否符合某种规则,符合的话,他们的积就是吸血鬼数

public static void main(String[] arg){
String[] ar_str1,ar_str2;
int sum=0;
//双重循环穷举
for(int i=10;i <100;i++){
//j=i+1避免重复
for(int j=i+1;j <100;j++){
int i_val=i*j;
if(i_val <1000 ¦ ¦i_val >9999)
continue; //积小于1000或大于9999排除,继续下一轮环
ar_str1=String.valueOf(i_val).split("");
ar_str2=(String.valueOf(i)+String.valueOf(j)).split("");
java.util.Arrays.sort(ar_str1);
java.util.Arrays.sort(ar_str2);
if(java.util.Arrays.equals(ar_str1, ar_str2)){
//排序后比较,为真则找到一组
sum++;
System.out.println("第"+sum+"组: "+i+"*"+j+"="+i_val);
}
}
}
System.out.println("共找到"+sum+"组吸血鬼数");
}

第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组吸血鬼数
dyw31415926 2007-10-31
  • 打赏
  • 举报
回复
运行结果
1260is xixuegui21*60
1395is xixuegui15*93
1435is xixuegui41*35
1530is xixuegui51*30
1827is xixuegui21*87
2187is xixuegui27*81
6880is xixuegui86*80
加载更多回复(1)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧