论坛首页 综合技术论坛

java编程思想的一道题(吸血鬼数字)

浏览 12991 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-01-13   最后修改:2012-01-13
我也写了一个~献丑

	void findNum()
	{
		for(int i = 10 ;i<100;i++)
		{
			for(int j = i ;j <100 ;j++)
			{
				if(equ(i,j))
				{
					System.out.printf("%d * %d = %d",i,j,i*j).println();					
				}
			}			
		}		
	}
	boolean equ(int i1 , int i2)
	{
		String strResult = Integer.valueOf(i1*i2).toString();
		String strI1 = Integer.valueOf(i1).toString();
		String strI2 = Integer.valueOf(i2).toString();
		int tmpLen = strResult.length();
		for(int i = 0;i<tmpLen;i++)
		{
			String tmpStr = strResult.substring(i, i+1);	
			int index1 = strI1.indexOf(tmpStr);
			int index2 = strI2.indexOf(tmpStr);
			if( index1 ==-1 && index2 ==-1 )
				break;
			if(index1 != -1)
				strI1 = strI1.substring(0,index1) + strI1.substring(index1+1);
			else
				strI2 = strI2.substring(0,index2) + strI2.substring(index2+1);
		}
		if(strI1.equals("")&&strI2.equals(""))
			return true;			
		else 
			return false;
	}
0 请登录后投票
   发表时间:2012-01-15   最后修改:2012-01-15
hubeen 写道
不知道你要的简单是指代码少还是效率高。
我写了个穷举的算法。
public class Test {


	public void vampireNumber() {
		for (int i = 10; i < 100; i++) {
			for (int j = 10; j < 100; j++) {
				int product = i * j;
				if (product > 1000 && product < 10000 && product % 100 != 0 && isEqual(product, i, j)) {
					System.out.println(product + "=" + i + "*" + j);
				}
			}
		}
	}


}

我觉得这部分可以修改一下:
public class Test {


	public void vampireNumber() {
		for (int i = 10; i < 100; i++) {
			for (int j = i*i>1000 ? i : (1000/i + 1); j < 100; j++) {
				int product = i * j;
				if (product % 100 != 0 && isEqual(product, i, j)) {
					System.out.println(product + "=" + i + "*" + j);
				}
			}
		}
	}
}
0 请登录后投票
   发表时间:2012-01-16  

  下面为小弟能想到的比较高效的方法了!

 

 

 

package com.archermind;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/*  吸血鬼数字是指位数为偶数的数字,可以由一对数字相乘而得到,
 *  而这对数字各自包含乘积的一半位数的数字,其中从最初的数字中选取的数字任意排序,
 *  以2个0结尾的数字是不允许的比如说下面的数字是吸血鬼数字
 * 
 *  1260 = 21 × 60
 *  1827 = 21 × 87
 *  2187 = 27 × 81
 * 
 *  问题:写一个程序,找出4位数字所有吸血鬼数据
 */
public class VampireNumber {

    /* 循环次数 */
    private static int count;

    /* 吸血鬼数字,其key部分存放的为吸血鬼数字,value部分为两个乘数 */
    private static Map<Integer, String> vampireMap = new HashMap<Integer, String>();

    public static void main(String[] args) {

        findVampireNumber();
        Set<Entry<Integer, String>> set = vampireMap.entrySet();
        Iterator<Entry<Integer, String>> it = set.iterator();
        while (it.hasNext()) {

            Entry<Integer, String> e = it.next();
            System.out.println(e.getKey() + "=" + e.getValue());
        }
        System.out.println("共循环: " + count);
    }

    public static void findVampireNumber() {

        int vampireNumber = 0;

        int startNumber = 11;//初始值从11开始,10明显不满足筛选条件
        int stopNumber = 100;

        for (int i = startNumber; i < stopNumber; i++) {

            int j = startNumber;

            /* 尽量减少无效循环,j值根据i值的变化而变化
             * 此处j值的选择是通过与最小i值相乘是否大于1000
             * 为原则
             * */
            if (10 < i && i < 20) {

                j = 90;
            } else if (20 <= i && i < 30) {

                j = 50;
            } else if (30 <= i && i < 40) {

                j = 35;
            } else if (40 <= i && i < 50) {

                j = 25;
            } else if (50 <= i && i < 60) {

                j = 20;
            }

            for (; j < stopNumber; j++) {

                count++;

                vampireNumber = i * j;

                if (vampireNumber > 1000) {

                    /* 过滤掉诸如10*10、40*50、50*60、60*70等类似的组合 */
                    if (((i % 10) == 0) && ((j % 10) == 0)) {
                        // System.out.println("i: " + i + " , j: " + j);
                    } else {

                        if(isEqual(vampireNumber,i,j)){
                            vampireMap.put(vampireNumber, i + "*" + j);
                        }
                    }
                }
            }
        }
    }

    public static boolean isEqual(int vam,int a,int b) {

        char [] c1 = String.valueOf(vam).toCharArray();
        char [] c2 = (a + String.valueOf(b)).toCharArray();
       
        Arrays.sort(c1);
        Arrays.sort(c2);
        return Arrays.equals(c1, c2);
    }
}

0 请登录后投票
   发表时间:2012-01-18  
wei5201 写道
我来回复一个吧:

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;

public class test {
	public static void main(String args[]) {
		for(int x=10;x<100;x++){
			for(int y=10;y<100;y++){
				if(chen(x,y)){//如果是魔鬼数的话则打印出来,同时把这对相乘的数也打印出来
					System.out.println(x*y+"="+x+"*"+y);
				}
			}
		}
	}

	/**
	 * 判断x,y的乘积是否是魔鬼数
	 * @param x
	 * @param y
	 * @return
	 */
	public static boolean chen(int x, int y) {
		int z = x * y;
		String s = String.valueOf(z);
		if (s.length() == 4) {
			String a = String.valueOf(s.charAt(0));
			String b = String.valueOf(s.charAt(1));
			String c = String.valueOf(s.charAt(2));
			String d = String.valueOf(s.charAt(3));
			Map<String,String> list = zuhe(a,b,c,d);
			return isHeshi(x,y,list);
		}
		return false;
	}

	/**
	 * 这个4位数的乘积可以组合成多少种2位数配对的组合
	 * 
	 * @param a
	 * @param b
	 * @param c
	 * @param d
	 * @return
	 */
	public static Map<String,String> zuhe(String a, String b, String c, String d) {
		List<String> l = new ArrayList<String>();
		l.add(a);
		l.add(b);
		l.add(c);
		l.add(d);
		
		Map<String,String> list = new HashMap<String,String>();
		for (String dd : l) {
			List<String> ll = new ArrayList<String>();
			ll.add(dd);
			Collection<String> cc = CollectionUtils.subtract(l, ll);
			for (String e : cc) {
				List<String> lll = new ArrayList<String>();
				lll.add(dd);lll.add(e);
				Collection<String> ccc = CollectionUtils.subtract(l, lll);
				String o ="";
				for(String g:ccc){
					o=o+g;
				}
				list.put(dd+e, o);
			}
		}	
		
		return list;
	}

	/**
	 * 判断原始相乘的一对数是否在排列组合后的2位数的组合中,如果是的话,那么这 对数相乘后的数字就是魔鬼数字
	 * 
	 * @param x
	 *            原始相乘的数x
	 * @param y
	 *            原始相乘的数y
	 * @param l
	 *           这个4位数的乘积可以组合成多少种2位数配对的组合
	 * @return
	 */
	public static boolean isHeshi(int x, int y, Map l) {
		String s = String.valueOf(x);
		String s2 = String.valueOf(y);
		if (l.get(s)!=null && l.get(s).equals(s2)){
			return true;
		}
		return false;
	}
}


这个效率不高啊! 花了156ms
0 请登录后投票
   发表时间:2012-01-18   最后修改:2012-01-18
饭特稀 写道
我也写了一个~献丑

	void findNum()
	{
		for(int i = 10 ;i<100;i++)
		{
			for(int j = i ;j <100 ;j++)
			{
				if(equ(i,j))
				{
					System.out.printf("%d * %d = %d",i,j,i*j).println();					
				}
			}			
		}		
	}
	boolean equ(int i1 , int i2)
	{
		String strResult = Integer.valueOf(i1*i2).toString();
		String strI1 = Integer.valueOf(i1).toString();
		String strI2 = Integer.valueOf(i2).toString();
		int tmpLen = strResult.length();
		for(int i = 0;i<tmpLen;i++)
		{
			String tmpStr = strResult.substring(i, i+1);	
			int index1 = strI1.indexOf(tmpStr);
			int index2 = strI2.indexOf(tmpStr);
			if( index1 ==-1 && index2 ==-1 )
				break;
			if(index1 != -1)
				strI1 = strI1.substring(0,index1) + strI1.substring(index1+1);
			else
				strI2 = strI2.substring(0,index2) + strI2.substring(index2+1);
		}
		if(strI1.equals("")&&strI2.equals(""))
			return true;			
		else 
			return false;
	}

花了47ms 楼上大多是16ms的 还有少于1ms的 不过实现的思路不错 学习了
0 请登录后投票
   发表时间:2012-02-04  
p363266860 写道
自己想的,很丑陋很局限的一种解法,应该是最高效的了,ON
	public static void solution1 () {
		for (int i=1000;i<9999;i++) {
			int a = i/1000;
			int b = i%1000/100;
			int c = i%100/10;
			int d = i%10;

			if (i == (a*10 + b)*(c*10 + d)) {
				System.out.println(i + " = " + a + b + " * " + c + d);
			} else if (i == (a*10 + b)*(d*10 + c)) {
				System.out.println(i + " = " + a + b + " * " + d + c);				
			} else if (i == (b*10 + a)*(c*10 + d)) {
				System.out.println(i + " = " + b + a + " * " + c + d);				
			} else if (i == (b*10 + a)*(d*10 + c)) {
				System.out.println(i + " = " + b + a + " * " + d + c);			
			} else if (i == (a*10 + c)*(b*10 + d)) {
				System.out.println(i + " = " + a + c + " * " + b + d);			
			} else if (i == (a*10 + c)*(d*10 + b)) {
				System.out.println(i + " = " + a + c + " * " + d + d);		
			} else if (i == (c*10 + a)*(b*10 + d)) {
				System.out.println(i + " = " + c + a + " * " + b + d);		
			} else if (i == (c*10 + a)*(d*10 + b)) {
				System.out.println(i + " = " + c + a + " * " + d + b);		
			} else if (i == (a*10 + d)*(c*10 + b)) {
				System.out.println(i + " = " + a + d + " * " + c + b);
			} else if (i == (a*10 + d)*(b*10 + c)) {
				System.out.println(i + " = " + a + d + " * " + b + c);
			} else if (i == (d*10 + a)*(c*10 + b)) {
				System.out.println(i + " = " + d + a + " * " + c + b);
			} else if (i == (d*10 + a)*(b*10 + c)) {
				System.out.println(i + " = " + d + a + " * " + b + c);
			}
		}
	}


这还是穷举啊,其实起码通过两个数的个位相乘是否等于原数的个位就可以排除一半了
0 请登录后投票
   发表时间:2012-02-14   最后修改:2012-02-14
给自个儿留个坑

for (i in 10..99)
  for (j in 10..99)
    if (numMatch(i, j , i*j)) { println i + " x " + j + " = " + (i*j) }
    
def numMatch(int i, int j, int k) {
  if (k < 1000 || k > 10000) return false;
  ca1 = ("" + i + j).toCharArray()
  ca2 = ("" + k).toCharArray()
  
  Arrays.sort(ca1)
  Arrays.sort(ca2)
  
  return Arrays.equals(ca1,ca2)
}

0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics