接下来我决定解决Project Euler problem 233,但我遇到了一些重大问题!我做了一些分析并取得了一些相当不错的进展,但我现在已经陷入困境。这是我的工作:
引理1 : 由于圆圈经过4个角点,因此任何n都至少有4个解。但是对于圆周上的每个点,有7个其他点被发现有反射。因此总有8k + 4个格点。
引理2 : 圆具有半径(√2)n和中心(n / 2,n / 2),因此其方程为(x-n / 2)^ 2 +(y-n / 2)^ 2 = [n/√2] ^ 2。这减少到x ^ 2 + y ^ 2 = n(x + y)。
引理3 : 如果写入x ^ 2 + y ^ 2 = n(x + y)的解(x,y,z),则另一解是(kx,ky,kz)。证明是:
(x+y)n = x^2+y^2
(kx)^2+(ky)^2 = (kx+ky)m
k(x^2+y^2) = (x+y)m
m = kn
这与我对这一思路的影响一样多 - 我看不到任何地方可以从那里去,但它包括在内,因为它可能很有用。
我的下一个想法是移动圆圈的中心。将有相同数量的解决方案在任何维度上移动整个整数。所以当n / 2是整数时,所以n = 2k,x ^ 2 + y ^ 2 = 2 * k ^ 2。而且事实证明,这个等式的解决方案与方程x ^ 2 + y ^ 2 = k ^ 2一样多(见Sloane A046109)。
这也提供了一种简单的方法来计算任何n通过A046080的解决方案的数量。如果4k + 1形式的n中素数的幂是f [0] ... f [m],那么解的数量是4 *乘积(2f [i] +1 | i in [0 .. .M])。
这允许我向后工作:4.product(2f [i] +1 | i in [0 ... m])= 420,所以乘积(2f [i] +1 | i in [0 .. .m])= 105 = 3 * 5 * 7。我能够想出这个程序,我认为找到所有n的总和,形式为2k且小于10 ^ 11,其中有420个圆格点。答案(我希望!)是257199853438240692。
这是C程序:
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#include "string.h"
#define lim 1000000000L
char prime[lim];
long primes[50000000];
long len = 0;
int main(void)
{
long i, j;
for(i = 0; i < lim; i++)
{
prime[i] = 1;
}
for(i = 2; i < lim; i++)
{
if(prime[i])
{
for(j = 2*i; j < lim; j += i) prime[j] = 0;
if((i-1)%4 == 0)
{
prime[i] = 2;
//printf("%li\n", i);
primes[len++] = i;
}
}
if(i < 1000 || (i < 10000 && i%1000 == 0) || i%10000 == 0) printf("%li, %li\n", i, len);
}
printf("primes!\n");
long a, b, c, v, total = 0, k;
for(a = 0; a < len; a++)
{
v = primes[a]*primes[a]*primes[a];
if(v > 50000000000L) break;
for(b = 0; b < len; b++)
{
if(b == a) continue;
v = primes[a]*primes[a]*primes[a]*primes[b]*primes[b];
if(v > 50000000000L) break;
for(c = 0; c < len; c++)
{
if(c == a) continue;
if(c == b) continue;
v = primes[a]*primes[a]*primes[a]*primes[b]*primes[b]*primes[c];
if(v > 50000000000L) break;
for(k = 1; k*v <= 50000000000L; k++)
{
if(prime[k] == 2) continue;
total += k*v;
}
}
}
}
for(a = 0; a < len; a++)
{
v = primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a];
if(v > 50000000000L) break;
for(b = 0; b < len; b++)
{
if(b == a) continue;
v = primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[b]*primes[b]*primes[b];
if(v > 50000000000L) break;
for(k = 1; k*v <= 50000000000L; k++)
{
if(prime[k] == 2) continue;
total += k*v;
}
}
}
for(a = 0; a < len; a++)
{
v = primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a];
if(v > 50000000000L) break;
for(b = 0; b < len; b++)
{
if(b == a) continue;
v = primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[a]*primes[b]*primes[b];
if(v > 50000000000L) break;
for(k = 1; k*v <= 50000000000L; k++)
{
if(prime[k] == 2) continue;
total += k*v;
}
}
}
printf("%li\n", 2*total);
return 0;
}
我们只需要添加具有420个圆格点的n的值,并且形式为2k + 1!然而,这似乎比n = 2k更难,我看不到任何方法。我也有点不确定我的答案是否正确,因为这个方法很复杂......任何人都可以证实吗?是否有一种简洁的方法,不涉及不同的n处理?
我完全没有想法!
我最感兴趣的是我如何处理N = 2k + 1,因为当N = 2k时,我可以像John Feminella所说的那样做。
答案 0 :(得分:9)
提示1:圆的半径为n /√2,对于整数n从不是整数,因此A046080永远不会适用。
提示2:不要打扰周围的圆圈。从方格纸上拿起它,然后想一想,定义它的方块,以及相对于彼此的圆周上尚未知的兴趣点。
提示3:半圆内接的角度始终为90度。
提示4:一个数字可以写成两个方格的总和?
奖金提示在整个过程中自由使用:对称!
在您尝试从上面的提示中解决之前,请不要进一步阅读
如果这些提示不够,以下是与上述提示交错的一些缺失步骤:
提示1.5:由于您使用的方法基于有缺陷的前提,因此您将不得不改变查看问题的方式。
提示2.5:想想广场顶角之间弧线左侧的格点。通过对称,在它的右边有另一个这样的点,而在下面直接有第三个点。关于这些点之间的距离以及它们形成的角度,你能说些什么呢?
提示3.5:如何确定任何给定n的正方形顶角之间弧的左侧有多少个格点?
答案 1 :(得分:1)
提示#1。你的引理#2不太正确。你确定这是半径吗?
提示#2。答案与平方和函数r(k,n)密切相关。这给出了使用k个不同方块表示n的方式的数量,允许零并区分顺序。例如,r(2,5)是8,因为有8种方法用2个方块表示5:
(-2)^2 + (-1)^2
(-2)^2 + 1^2
2^2 + (-1)^2
2^2 + 1^2
... (and the 4 additional expressions produced by reversing these 2 terms)
您可以看到以原点为中心的半径为p的圆具有r(2,p ^ 2)点阵点。例如,半径为5的圆具有:
(-4)^2 + (-3)^2
... and 7 others like this
5^2 + 0^2
(-5)^2 + 0^2
0^2 + 5^2
0^2 + (-5)^2
总共12个。什么类型的数字会有420个圆格点?如果他们不是以原点为中心呢?我会让你从这里拿走它。
如果你想要一个更大的提示,我已经腐烂了13(http://rot13.com)你应该在这里查看:
uggc://zngujbeyq.jbysenz.pbz/FpuvamryfGurberz.ugzy
答案 2 :(得分:0)
您可以参考http://oeis.org/A046109/b046109.txt来检查多达1000个。我在这里安装了PARI / GP并使用了一种PARI脚本:http://oeis.org/A046109检查更高的数字。