我现在正在努力争取我的Project Euler#12代码约3个小时。我实现了为数字超过130个除数的情况节省了几秒钟,我的第一个程序达到2.33秒,现在它在1.169秒内完成。但是我从来没有耐心等待500的除数。如何固定我的代码?我尝试了从n和n + 1得到除数的情况,但它只是减慢了我的程序......这是我的代码。
static bool isPrime(int num) {
if (num % 2 == 0 && num != 2)
return false;
else
for (int i = num; i < Math.Sqrt(num) + 1; i++) {
if (num % i == 0)
return false;
}
return true;
}
static void Main(string[] args) {
Stopwatch time = new Stopwatch();
time.Start();
int trianglenumber = 0;
int divizori = 0;
for (int i = 3; i < Int32.MaxValue; i+=2) {
if (isPrime(i) != false) {
int tempnumber = 0;
tempnumber = (i * (1 + i)) / 2;
for (int k = 1; k < tempnumber + 1; k++) {
if (tempnumber % k == 0) {
divizori++;
}
}
if (500 < divizori) {
trianglenumber = tempnumber;
break;
}
divizori = 0;
}
}
time.Stop();
double timp = time.ElapsedMilliseconds ;
Console.WriteLine(trianglenumber);
Console.Write("Runtime: " + timp/1000 + " seconds");
Console.ReadKey();
}
答案 0 :(得分:2)
大减速是在你的isPrime()方法中。
通过素数分解来计算计数因子。你会发现计算500个因素的速度要快得多。
http://www.mathsisfun.com/prime-factorization.html
此外,您如何获得三角数应该更简单。
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
注意每个连续数字组之间的差异......
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10+ 5 = 15
15+ 6 = 21
等等......看看那个中间数字。
仅供参考,我使用素数分解方法的版本需要大约6ms来找到答案....非常快。
答案 1 :(得分:0)
围绕这个问题的一些Python函数。它使用Counters,完美 高水平的工具来做到这一点。希望这可以帮助您找到密钥增强功能。
from collections import Counter
def factors(n):
divisor=2
while divisor*divisor<=n:
if n%divisor==0:
return Counter({divisor:1})+factors(n//divisor)
divisor += 1
return Counter({n:1}) # prime number
def nbdiv(factors):
p=1
for factor in factors : p *= factors[factor]+1
return p
def nbdivtri(n):
a,b=n,n+1
if a%2==0 : a//=2
else: b//=2
return nbdiv(factors(a)+factors(b))
答案 2 :(得分:0)
我用小于0.187毫秒的贪婪算法解决了这个问题。
static void Main(string[] args)
{
// 76576500
long age = 10000;
double alpha = 1.5;
double betta = 0.1;
Random ran = new Random();
long mmm = long.MaxValue;
double RR = 0;
var a = DateTime.Now;
for (int i = 0; i < 5000; i++)
{
long N = age * (age + 1) / 2;
long count = 0;
for (int j = 2; N!=1; j++)
{
int c = 0;
while (N % j == 0)
{
N /= j;
c++;
}
count = (count + 1) * (c + 1) - 1;
}
double r = ran.Next() % 11;
r = 1 / (Math.Pow(r, alpha) + 1);
long R = (long)r + 1;
if (count >= 500)
{
alpha *= 1 + 0.001;
RR = RR * betta - (1-betta) * R;
N = age * (age + 1) / 2;
if (N < mmm)
{
mmm = N;
Console.WriteLine(mmm);
}
}
else
{
alpha *= 1 - 0.001;
RR = RR * betta + (1 - betta) * R;
}
age += (long)RR;
}
var b = DateTime.Now - a;
Console.WriteLine("R=" + mmm + " " + b);
string sss = Console.ReadLine();
}