Pandigital产品总和

时间:2009-11-13 21:59:49

标签: java

我正试图解决这个问题:

  

如果使用的话,我们会说n位数是pandigital   所有数字1到n恰好一次;例如,5位数字,   15234,是1到5 pandigital。

     

产品7254不寻常,因为身份,39×186 = 7254,   包含被乘数,乘数和乘积是1到9   pandigital。

     

查找其被乘数/乘数/乘积的所有乘积的总和   身份可以写成1到9 pandigital。

     

提示:某些产品可以通过多种方式获得,因此请务必使用   把它包括在你的总和中。

但我没有得到正确的答案。

我做错了什么?

这是我的尝试:

public class Euler32 {

    public static boolean checkValue(char c,String s,int j) {    
        for(int i=j+1;i<s.length();i++)
            if(c==s.charAt(i)) 
                return true;      
        return false;
    } 

    public static void main(String[] args) {
        long total=0;
        long sum=0;

        for(int i1=40;i1<=999;i1++) {   
            for(int j=130;j<=9999;j++) {
                sum=i1*j;
                String s=i1+""+j+""+sum;

                if(s.length()!=9) continue;

                else {
                    for(int i=0;i<s.length()-1;i++) {
                        if(checkValue(s.charAt(i),s,i))
                            break;          
                        if(i+1==s.length()-1) 
                            total+=sum;      
                    }
                } 
            }
        }
        System.out.println("Total sum is: "+total);
    }    
}

3 个答案:

答案 0 :(得分:1)

好的,很少说明:

  1. 你从40开始的假设是不正确的,因为4 * 1783 = 6952是pandigital。还有一个你缺少的那个:)
  2. 您不排除重复的产品。
  3. 根据与Marius的讨论,我在这里更新原始答案。 这只是isPandigital方法。

    private boolean isPandigital(int a,int b){
       int c=a*b;
       StringBuilder st =  new StringBuilder();
       st.append(a).append(b).append(c);
    
       if (st.length()!=9 || st.indexOf("0")>-1) return false;
    
       Set<Character> x=new TreeSet<Character>();
    
       for (int i=0;i<9; i++){
           x.add(st.charAt(i));
       }
      if (x.size()==9){
         for (int k=0;k<=cnt;k++){
            if (products[k]==c) return false;
         }
      products[++cnt]=c;
      total += c;
    
      return true;
      }
     return false;
    }
    

    我比较了我机器上的两个代码,然后是十次尝试平均值,结果如下:

    1. Marius代码:平均(2070毫秒)
    2. medopal code:average(2200ms)
    3. Marius代码(使用String):average(4200ms)
    4. medopal code(使用String):average(5000ms)
    5. 我添加了String vs StringBuilder的比较,因为显然它是让原始代码变得如此缓慢的原因。但是使用StringBuilder,Marius代码只能在平均200ms内击败我:)

      经验教训:

      • StringBuilder花费的时间几乎是String的一半。 (至少在这个实验中)
      • 当你懒惰思考时,你可以使用现成的结构。 (至少在这个实验中),我不是概括

      谢谢马吕斯:)

答案 1 :(得分:0)

你遗漏了一些观点:

  1. 是1..9
  2. 独特的产品
  3. 你怎么用40和130(只是好奇)
  4. (记住,理解问题解决了50%)

    建议:

    1. 了解continue [label];语句并使用本地for循环而不是checkValue
    2. 为什么不止一次使用s.length()?
    3. 使用StringBuilder

答案 2 :(得分:0)

这是另一种实现。有一些评论可以看出我决定如何选择较低上限

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/*
 * 15234, is 1 through 5 pandigital.
 * The product 7254 is unusual: 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
 * Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
 * HINT: Some products can be obtained in more than one way so be sure to only include it once in your sum.
 */
public class P32 {
    /* Obs:
     * 1) Because x * y = y * x, let's consider x < y (avoid duplicates)
     * 2) f * abcde => at least 1 + 5 + 5 = 11 digits => too long => y <= 9876
     * 3) If x has 3 or more digits => at least 3 + 3 + 5 = 11 digits => too long
     *    x <= 98
     * 4) If y has 2 digits => at most 8 digits => y >= 123
     * 5) If x = 1 => y and product have the same value
     * */

    final private static int min = 2;
    final private static int maxOfTwoDigits = 98;
    final private static int minOfThreeDigits = 123;
    final private static int max = 9876;

    public static void main(String args[]) {
        Set<Integer> goodProducts = new HashSet<Integer>();
        for (int multiplicand = min; multiplicand <= maxOfTwoDigits; multiplicand++) {
            for (int multiplier = minOfThreeDigits; multiplier <= max; multiplier++) {
                int product = multiplicand * multiplier;
                List<Integer> multiplicandDigits = getDigits(multiplicand);
                List<Integer> multiplierDigits = getDigits(multiplier);
                List<Integer> productDigits = getDigits(product);
                if (multiplicandDigits.size() + multiplierDigits.size()
                        + productDigits.size() == 9) {
                    productDigits.addAll(multiplierDigits);
                    productDigits.addAll(multiplicandDigits);
                    for (int i = 1; i <= 9; i++) {
                        productDigits.remove((Integer) i);
                    }
                    if (productDigits.size() == 0) {
                        goodProducts.add(product);
                    }
                }
            }
        }
        System.out.println(getSum(goodProducts));
    }

    private static List<Integer> getDigits(int x) {
        List<Integer> digits = new ArrayList<Integer>();
        while ( x > 0 ) {
            digits.add(x%10);
            x/=10;
        }
        return digits;
    }

    private static long getSum(Set<Integer> s) {
        long sum = 0;
        for ( Integer i : s) {
            sum += i;
        }
        return sum;
    }

}

<强>解释

  • 它会将一些数字(在指定的时间间隔内)相乘以获得产品。
  • 对于所有3个数字,它获取数字,如果总位数为9,则所有数字都会添加到同一个列表中。
  • 然后从列表中删除数字1到9,如果列表中有0个元素,则表示该组合是pandigital。
  • 为避免重复,将产品添加到一个集合中。

时间: 362 ms