Java 投影Euler Prob 12,取2
我又在这里绞尽脑汁,与欧拉计划第12题搏斗。它要求第一个三角形数的除数超过500 以下是我以前的尝试: 我收到了很多很好的建议,我努力尝试去应用 感谢你们的回复,现在我可以:筛选出一个非常高的素数,对任意数进行素数分解,并计算除数 但是我不能把这些技术和寻找500个除数的三角形数的问题联系起来。所以我已经筛选出了大量的素数,那么我该怎么做呢?我对任何数字进行因式分解并计算其除数,那么如何使用它来解决这个问题呢 我回到我以前的试用解决方案并清理了代码。现在它可以找到除数低的三角形数。但是,在达到500的情况下,编译器会继续运行 以下是我的清理解决方案:Java 投影Euler Prob 12,取2,java,Java,我又在这里绞尽脑汁,与欧拉计划第12题搏斗。它要求第一个三角形数的除数超过500 以下是我以前的尝试: 我收到了很多很好的建议,我努力尝试去应用 感谢你们的回复,现在我可以:筛选出一个非常高的素数,对任意数进行素数分解,并计算除数 但是我不能把这些技术和寻找500个除数的三角形数的问题联系起来。所以我已经筛选出了大量的素数,那么我该怎么做呢?我对任何数字进行因式分解并计算其除数,那么如何使用它来解决这个问题呢 我回到我以前的试用解决方案并清理了代码。现在它可以找到除数低的三角形数。但是,在达到
public static void main(String[] args) {
long c=2;
long d=(c*(c+1)/2);
while (numDivs(d)<=500) {
c++;
d=(c*(c+1)/2);
}
System.out.println(d);
System.out.println(c);
}
public static long numDivs(long a) {
long foo=2;
for (long b=1;b*2<=a;b++ ) {
if (a%b==0)
foo++;
}
return foo;
}
publicstaticvoidmain(字符串[]args){
长c=2;
长d=(c*(c+1)/2);
而(numDivs(d)我认为第一件事,一个人可以做的,是以两倍的速度计算除数,只需在数的sqrt
处剪切:
public static long numDivs(long a) {
if(a == 1)
return 1;
long num = 2;
int sqrt = (int) Math.sqrt(a);
if(sqrt*sqrt == a) {
num++;
}
for (long b = 2;b < sqrt; b++) {
if (a%b == 0) {
num += 2;
}
}
return num;
}
公共静态长NUMDIV(长a){
如果(a==1)
返回1;
长数=2;
intsqrt=(int)Math.sqrt(a);
如果(sqrt*sqrt==a){
num++;
}
用于(长b=2;b
基本原理:如果除数大于数字的平方根,则它有一个较小的辅除数,而不是单独计算,您可以同时计算两者
这肯定会产生影响,因为numDivs
现在的时间复杂度是O(sqrt n),而不是O(n)。我认为您尝试应用的算法非常幼稚
检查我的代码,我认为它使用了更好的方法
寻找素数
私有静态列表筛选(int maxPrime){
boolean[]isPrime=新的boolean[maxPrime];
列表素数=新的ArrayList();
数组.fill(isPrime,true);
对于(int i=2;i*i
因式分解
这里我们得到一个映射,其中key是因子,value是它发生的次数
private static Map<Integer, Integer> factorize(List<Integer> primes, int number) {
Map<Integer, Integer> factors = new HashMap<>();
int tempNumber = number;
for (Integer prime : primes) {
while (tempNumber % prime == 0) {
tempNumber = tempNumber / prime;
if (factors.containsKey(prime)) factors.put(prime, factors.get(prime) + 1);
else factors.put(prime, 1);
}
}
return factors;
}
私有静态映射分解(列表素数,整数){
映射因子=新的HashMap();
int TEMPNAME=数字;
for(整数素数:素数){
while(tempNumber%prime==0){
tempNumber=tempNumber/素数;
if(factors.containsKey(prime))factors.put(prime,factors.get(prime)+1);
其他因素。put(prime,1);
}
}
回报因素;
}
计数因子
private静态int计数因子(映射因子){
int结果=1;
对于(整数c:factors.values()){
结果*=c+1;
}
返回结果;
}
行刑
publicstaticvoidmain(字符串[]args){
final int MAX_PRIME=(int)Math.sqrt(Integer.MAX_VALUE);
列表素数=筛(最大素数);
int triangularNumber=0;
对于(int i=1;i500){
打破
}
}
System.out.println(“数字”+三角形数字);
}
您不必每次都重新计算三角形数,只需添加c作为
T(n) = T(n-1) + n
所以代码明智
long c=2;
long d=(c*(c+1)/2);
while (numDivs(d)<=500) {
c++;
d += c;
}
长c=2;
长d=(c*(c+1)/2);
虽然(numDivs(d)这个问题似乎离题了,因为它是关于检查代码,而不是一个具体的可回答问题什么是三角形数?@CommuSoft@luigimendoza:嗯,这是一个三角形数,只是想在投资于结果不同的东西之前检查一下;)@CommuSoft euler项目中的问题链接中也解释了这一点:)谢谢。“num”的用途是什么?@bircadian:num
是除数,在答案中修复了它。
public static void main(String[] args) {
final int MAX_PRIME = (int) Math.sqrt(Integer.MAX_VALUE);
List<Integer> primes = sieve(MAX_PRIME);
int triangularNumber = 0;
for (int i = 1; i < Integer.MAX_VALUE; i++) {
triangularNumber += i;
Map<Integer, Integer> factors = factorize(primes, triangularNumber);
int total = countDivisors(factors);
if (total > 500) {
break;
}
}
System.out.println("The number " + triangularNumber);
}
T(n) = T(n-1) + n
long c=2;
long d=(c*(c+1)/2);
while (numDivs(d)<=500) {
c++;
d += c;
}