1 条题解

  • 0
    @ 2025-4-10 11:34:46

    解题思路

    题目要求计算一个正整数 nn 作为最多四个正平方数之和的所有表示的数量。根据拉格朗日四平方定理,任何正整数都可以表示为最多四个正平方数的和。我们需要找到所有可能的组合,并计算它们的数量。为了确保不重复计算相同的组合,我们可以通过限制平方数的顺序来避免重复。

    具体步骤:

    1. 处理1个平方数的情况

      • 检查 nn 是否是一个完全平方数。如果是,则计数加1。
    2. 处理2个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n2a^2 \leq \frac{n}{2}
      • 对于每个 aa,计算剩余部分 rem=na2rem = n - a^2
      • 检查 remrem 是否也是一个完全平方数,并且 bab \geq a。如果是,则计数加1。
    3. 处理3个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n3a^2 \leq \frac{n}{3}
      • 对于每个 aa,计算剩余部分 rem1=na2rem1 = n - a^2
      • 再次遍历所有可能的平方数 b2b^2,使得 b2rem12b^2 \leq \frac{rem1}{2}
      • 对于每个 bb,计算剩余部分 rem2=rem1b2rem2 = rem1 - b^2
      • 检查 rem2rem2 是否也是一个完全平方数,并且 cbc \geq b。如果是,则计数加1。
    4. 处理4个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n4a^2 \leq \frac{n}{4}
      • 对于每个 aa,计算剩余部分 rem1=na2rem1 = n - a^2
      • 再次遍历所有可能的平方数 b2b^2,使得 b2rem13b^2 \leq \frac{rem1}{3}
      • 对于每个 bb,计算剩余部分 rem2=rem1b2rem2 = rem1 - b^2
      • 再次遍历所有可能的平方数 c2c^2,使得 c2rem22c^2 \leq \frac{rem2}{2}
      • 对于每个 cc,计算剩余部分 rem3=rem2c2rem3 = rem2 - c^2
      • 检查 rem3rem3 是否也是一个完全平方数,并且 dcd \geq c。如果是,则计数加1。
    5. 输出结果

      • 将所有情况的计数相加,输出结果。

    代码实现

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    int main() {
        int n;
        while (cin >> n && n != 0) {
            int total = 0;
    
            // 处理1个数的情况
            int s = sqrt(n);
            if (s * s == n) {
                total += 1;
            }
    
            // 处理2个数的情况
            int count2 = 0;
            for (int a = 1; a * a <= n / 2; ++a) {
                int rem = n - a * a;
                int b = sqrt(rem);
                if (b * b == rem && b >= a) {
                    count2++;
                }
            }
            total += count2;
    
            // 处理3个数的情况
            int count3 = 0;
            for (int a = 1; a * a <= n / 3; ++a) {
                int rem1 = n - a * a;
                for (int b = a; b * b <= rem1 / 2; ++b) {
                    int rem2 = rem1 - b * b;
                    int c = sqrt(rem2);
                    if (c * c == rem2 && c >= b) {
                        count3++;
                    }
                }
            }
            total += count3;
    
            // 处理4个数的情况
            int count4 = 0;
            for (int a = 1; a * a <= n / 4; ++a) {
                int rem1 = n - a * a;
                for (int b = a; b * b <= rem1 / 3; ++b) {
                    int rem2 = rem1 - b * b;
                    for (int c = b; c * c <= rem2 / 2; ++c) {
                        int rem3 = rem2 - c * c;
                        int d = sqrt(rem3);
                        if (d * d == rem3 && d >= c) {
                            count4++;
                        }
                    }
                }
            }
            total += count4;
    
            cout << total << endl;
        }
        return 0;
    }
    

    代码解释

    1. 处理1个平方数的情况

      • 检查 nn 是否是一个完全平方数。如果是,则计数加1。
    2. 处理2个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n2a^2 \leq \frac{n}{2}
      • 对于每个 aa,计算剩余部分 rem=na2rem = n - a^2
      • 检查 remrem 是否也是一个完全平方数,并且 bab \geq a。如果是,则计数加1。
    3. 处理3个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n3a^2 \leq \frac{n}{3}
      • 对于每个 aa,计算剩余部分 rem1=na2rem1 = n - a^2
      • 再次遍历所有可能的平方数 b2b^2,使得 b2rem12b^2 \leq \frac{rem1}{2}
      • 对于每个 bb,计算剩余部分 rem2=rem1b2rem2 = rem1 - b^2
      • 检查 rem2rem2 是否也是一个完全平方数,并且 cbc \geq b。如果是,则计数加1。
    4. 处理4个平方数的情况

      • 遍历所有可能的平方数 a2a^2,使得 a2n4a^2 \leq \frac{n}{4}
      • 对于每个 aa,计算剩余部分 rem1=na2rem1 = n - a^2
      • 再次遍历所有可能的平方数 b2b^2,使得 b2rem13b^2 \leq \frac{rem1}{3}
      • 对于每个 bb,计算剩余部分 rem2=rem1b2rem2 = rem1 - b^2
      • 再次遍历所有可能的平方数 c2c^2,使得 c2rem22c^2 \leq \frac{rem2}{2}
      • 对于每个 cc,计算剩余部分 rem3=rem2c2rem3 = rem2 - c^2
      • 检查 rem3rem3 是否也是一个完全平方数,并且 dcd \geq c。如果是,则计数加1。
    5. 输出结果

      • 将所有情况的计数相加,输出结果。
    • 1

    信息

    ID
    1043
    时间
    1000ms
    内存
    30MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者