给定数字N,有多少对数字的平方和小于或等于N?

时间:2015-12-24 17:07:30

标签: c++ algorithm math combinations

让我们将 F(N)定义为不同正整数(A,B)的对数,以便 A 2 + B 2 ≤N A< B

如果 N = 5 唯一可能的对(1,2) N = 10 这两对是 >(1,2)(1,3)

此外,我们有 F(13)= 3 F(17)= 4 F(17)= 4 F(20)= 5 F(20)= 5 F(25)= 6 F(100)= 31 < / em>等等,每个数字是两个不同的非零方块的总和。

到目前为止,我有以下解决方案:

long long SOLVE(lld n)
{
    long long x=sqrt(n),up=0;
    long long a=x,b=1;
    while(abs(a-(b-1))!=1)
    {

        while(sqr(a)+sqr(b)<=n )
        {
            b++;
        }
        up+=(b-1);
        a--;
    }
    b--;
    up+=(b*(b+1))/2;
    return up;
}
int main()
{
      cout<<number(100);
return 0;
}

相同的数字是不可数的,因此(1,1)(2,2)是无效的元组。 相同但不同的订单只计算一次。因此(1,2)(2,1)只计算一次。

但是由于 N 的范围是1,我需要一个更有效的算法或公式来计算它。有什么技巧可以让我的代码更有效率吗?

2 个答案:

答案 0 :(得分:4)

在伪代码中:

int count=0;
for (smaller=1; ;++smaller)
{
    maxlarger = floor(sqrt(N-smaller*smaller));
    if (maxlarger <= smaller)
        break;
    count+=(maxlarger-smaller);
}
return count;

答案 1 :(得分:1)

你不必计算 B 的数量:你可以简单地计算出可能的最大B,这就是 A <的立方数。 / EM>:

B max = sqrt(N-A 2 B 的下限是: 乙<子>分钟 = A + 1

现在您可以执行以下操作:

  • 1 迭代 A sqrt(n);
  • 为每个 A 计算您可以使用的 B 的数量;
  • 计算这些的总和。

因此,这引出了以下算法:

lld SOLVE(lld n) {
    lld aM=sqrt(n);
    lld a=1;
    lld res = 0;
    for(lld a = 1; a < aM; a++) {
        int nB = sqrt(n-a*a)-a;
        if(nB > 0) {
            res += nB;
        } else {
            break;
        }
    }
    return res;
}

从那时起,不再能找到 B 值,可以中断搜索。

我在这里写了demo这似乎有效。