您的位置:首页 > 其它

欧拉工程第32题:Pandigital product sum

2015-05-12 17:28 381 查看
题目链接:https://projecteuler.net/problem=32

题意:a*b=c 如果a、b、c三个数包含了1-9九个数字,则求出所有的C的乘积(C不能有重复的 ),如:39 × 186 = 7254

如果对a、b分别1-987654321两个for循环时间太长,不可取,太暴力。

要先判定a、b、c的取值范围在进行计算。

若a是1位数字,最大:9,则b最大是4位数字:9876,c最大是4位数字:9876

若a是2位数字,最大:98,则b最大是3为数字:987,c最大是4位数字:9876

若a是3位数字,最大:987,则b最大是2为数字:98,c最大是4位数字:9876

若a是4位数字,最大:9876,则b最大是1为数字:9,c最大是4位数字:9876

若a是5位数字,不满足a*b=c ,5位*1位!=3位

以上只是严格根据a、b、c的位数进行考虑各数的范围。

注意:

1.a*b=b*a 所有在运行中,第二个循环起始大小是第一个循环a的值

2.c的值不能重复,用TreeSet集合存储每个c

再加上a*b=c来判断a、b、c的范围

1.a最小值显然不能从1开始,b=c时候必然不满足三个数的各位数字是1-9

2.b的起始值应该是a+1,因为b不可能等于b,原因同上

3.根据上面判断可知道,a是一位数时候,b取得最大值,a的最小一位数是2,则b的最大值是9999/2=4999

4.根据a*b=b*a,则a的最大值也是4999

时间由5.5秒降到1.5秒,但是应该还是可以降低a、b的范围的。

手工运行程序发现:a的最小值是4,最大值是 1972,运行时间0.3s。

下面是最终代码:

package projecteuler31to40;

import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

class level32{
void solve(){//45228
int p;
int result=0;
int Min=4;
int Max=1972;
Set<Integer> set=new TreeSet<Integer>();
for(int a=Min;a<=Max;a++){
for(int b =a+1;b <=Max;b ++){
p=a*b ;
if(isPandigital(a,b,p)){
set.add(p);
}
}
}
Iterator it=set.iterator();
while(it.hasNext()){
int res=(Integer) it.next();//强制类型转换
result+=res;
}
System.out.println(result);
}
boolean isPandigital(int a,int b,int c){
StringBuilder st=new StringBuilder();
st.append(a).append(b).append(c);
//长度不为9,或者包含0
if(st.length()!=9||st.indexOf("0")>-1) return false;

Set<Character> set=new TreeSet<Character>();
for(int i=0;i<9;i++){
set.add(st.charAt(i));
}
//只有长度为9时候,说明包含1-9,9个数字
if(set.size()==9){
return true;
}else{
return false;
}
}

}
public class Problem32 {

public static void main(String[] args){
Date beginTime=new Date();
new level32().solve();
Date endTime=new Date();
Long Time=endTime.getTime()-beginTime.getTime();
System.out.println("Time:"+Time/1000+"s"+Time%1000+"ms");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: