Project Euler – Problem 12
来源:互联网 发布:js div删除classname 编辑:程序博客网 时间:2024/04/30 04:29
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, …
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
28可以表示为1*28,2*14,4*7
36可以表示为1*36,2*18,3*12,4*9,6*6
观察到:
1、T / 小于T的平方根的因子 = 大于T平方根的因子
2、T / T的平方根 = T的平方根
对于每个数,其平方根两侧有相同的因子个数。
static void TriangleNumberOver500Divisors(){ int t = 1; int a = 1; int cnt = 0; while (cnt < 500) { cnt = 0; a += 1; t += a; double r = Math.Sqrt(t); for (int i = 1; i < r; i++) { if (t % i == 0) cnt += 2; } // 当r正好为t的因子时,r被计数了两次。 if (t == r * r) cnt--; } Console.WriteLine(t);}
上面的办法速度太慢,当要求的因子个数增多时,耗时增加明显。
根据每个数可以分解为有限个素数的乘积,则
21 = (3^1)*(7^1)
28 = (2^2)*(7^1)
36 = (2^2)*(3^2)
我们用ai表示第i个素数因子,EXi表示第i个素因子的指数,D(T)表示triangle数T的因子个数。
那么T的因子可以表示为:从第i个素因子中拿出0到EXi个,从第j个素因子中拿出0到EXj个......
即,28的因子分别为 (2^0)*(7^0)=1, (2^1)*(7^0)=2, (2^2)*(7^0)=4, (2^0)*(7^1)=7, (2^1)*(7^1)=14, (2^2)*(7^1)=28。
所以,D(n)=(EXi+1)*(EXj+1)*......
D(21) = (1+1) * (1+1) = 4
D(28) = (2+1) * (1+1) = 6
D(36) = (2+1) * (2+1) = 9
另外,根据Triangle数的定义,T可以表示为N*(N+1)/2。当然,N和(N+1)必定互素,一偶一奇,不包含共同因子。那么
当N为偶数时:N/2和N+1
当N为奇数时:(N+1)/2和N
也互素!(8和9互素,4和9也互素。9和10互素,5和9也互素。相邻的两数互素,偶数折半与另一个也是互素的。)
简化D(T)计算:
D(T) = D(n)*D( (n+1) /2 ),当n为奇数。
D(T) = D(n/2)*D(n+1), 当n为偶数。
static void Find(){ int n = 3; int Dn = 2; int cnt = 0; int n1, Dn1, i, ex; int[] primeTable = GeneratePrimeTable(1000); // 计算D(N),然后计算D(N+1),不满足则使D(N+1)成为D(N),继续往下推进。 while (cnt <= 500) { n += 1; n1 = n; if (n1 % 2 == 0) n1 = n1 / 2; Dn1 = 1; for (i = 0; i < 1000; i++) { if (primeTable[i] * primeTable[i] > n1) { Dn1 *= 2; break; } ex = 1; while (n1 % primeTable[i] == 0) { ex++; n1 /= primeTable[i]; } if (ex > 1) Dn1 *= ex; if (n1 == 1) break; } cnt = Dn1 * Dn; Dn = Dn1; } Console.WriteLine((n - 1) * n / 2);}
函数中,产生素数表的函数参照Problem7的办法。
static int[] GeneratePrimeTable(int n){ int[] primeTable = new int[n]; primeTable[0] = 2; primeTable[1] = 3; primeTable[2] = 5; primeTable[3] = 7; int cnt = 3; int p = 11; while (cnt < n-1) { if (IsPrime(p)) { cnt++; primeTable[cnt] = p; } p += 2; } return primeTable;}static bool IsPrime(int n){ int r = (int)Math.Sqrt(n); int f = 5; while (f <= r) { if (n % f == 0) return false; if (n % (f+2) == 0) return false; f += 6; } return true;}
Tags: algorithm
- Project Euler – Problem 12
- Project Euler problem 12
- project euler problem 12
- Project Euler – Problem 10
- Project Euler – Problem 14
- Project Euler – Problem 16
- Project Euler – Problem 17
- Project Euler – Problem 18
- Project Euler – Problem 19
- Project Euler – Problem 20
- Project Euler – Problem 21
- Project Euler – Problem 22
- Project Euler – Problem 23
- Euler Project Problem 6
- project euler problem 11
- Project Euler Problem 81
- Project Euler Problem 60
- Project Euler Problem 59
- QWS
- sql2005 'sa'用户登录失败,解决方案
- Project Eluer - Problem 11
- Ajax基础
- Ubuntu_Ubuntu安装配置卸载JDK1.6
- Project Euler – Problem 12
- Win7下tomcat拒绝访问 Unable to open the service 'Tomcat7'
- (精)hdoj 2544(最短路,地杰斯特拉算法)(无向图)
- 网络中心招聘 我等来了我想要的
- Project Euler - Problem 13
- Project Euler – Problem 14
- Project Euler - Problem 15
- Project Euler – Problem 16
- 嵌入式LINUX开发入门