我正试图解决这个问题:
如果使用的话,我们会说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);
}
}
答案 0 :(得分:1)
好的,很少说明:
根据与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;
}
我比较了我机器上的两个代码,然后是十次尝试平均值,结果如下:
我添加了String vs StringBuilder的比较,因为显然它是让原始代码变得如此缓慢的原因。但是使用StringBuilder,Marius代码只能在平均200ms内击败我:)
经验教训:
谢谢马吕斯:)
答案 1 :(得分:0)
你遗漏了一些观点:
(记住,理解问题解决了50%)
建议:
continue [label];
语句并使用本地for循环而不是checkValue
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;
}
}
<强>解释强>:
时间: 362 ms 。