题解:洛谷 P2666 Bessie's Secret Pasture

【题目来源】

洛谷:P2666 [USACO07OCT] Bessie's Secret Pasture S - 洛谷

【题目描述】

Farmmer John 最近收割了几乎无限多块牧草,将它们堆放在空地上。这些牧草都是正方形的,而且都有非负整数长度的边长(当然有 \(0\))。一天它的奶牛 Bessie 发现了这些美味的牧草,于是希望把它们种在自己的秘密牧场上。他总将草皮分割成 \(1\times1\) 的小块,以放入他牧场上的 \(N\) 个格子中。

Bessie 感兴趣的是,她若选取四块会有多少种不同方法。如果 \(N=4\),那么她就有 \(5\) 种不同分法:\((1,1,1,1), (2,0,0,0), (0,2,0,0),(0,0,2,0),(0,0,0,2)\),括号内数表示边长。注意这里不讲究顺序,如 \((1,2,3,4)\)\((4,3,2,1)\) 是两种不同方法。

【输入】

仅一行,一个整数 \(N\)

【输出】

同样为一行,包含一个整数,为方案总数。

【输入样例】

4

【输出样例】

5

【核心思想】

  1. 问题分析:给定整数 \(N\),求选取四块正方形牧草(边长为非负整数,允许为 \(0\))使得总面积为 \(N\) 的方案数。四块牧草的面积分别为 \(i^2, j^2, k^2, l^2\),满足 \(i^2 + j^2 + k^2 + l^2 = N\)。这是一个四平方和枚举问题,关键在于直接暴力枚举四个边长并统计满足条件的组合数。

  2. 算法选择

    • 暴力枚举:四重循环枚举 \(i, j, k, l\)(范围 \(0\)\(\sqrt{N}\)),检查 \(i^2 + j^2 + k^2 + l^2 = N\)
    • 范围优化:由于 \(i^2 \le N\)\(i\) 最大为 \(\lfloor\sqrt{N}\rfloor\),当 \(N \le 10^4\) 时范围不超过 \(100\)
  3. 关键步骤

    • 读取输入:整数 \(N\)
    • 四重循环枚举\(i, j, k, l\)\(0\)\(100\)):
      • \(i^2 + j^2 + k^2 + l^2 = N\)\(ans \mathrel{+}= 1\)
    • 输出 \(ans\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O((\sqrt{N})^4) = O(N^2)\),四重循环,每重最多 \(\sqrt{N}\)
    • 空间复杂度:\(O(1)\),仅需常数个变量
  5. 暴力枚举的核心思想

    • 四平方和定理:任何非负整数都可表示为四个整数的平方和,本题是求表示方案数
    • 顺序即区分:题目明确 \((1,2,3,4)\)\((4,3,2,1)\) 是不同方案,因此无需去重,直接枚举所有有序四元组
    • 范围剪枝:边长上限为 \(\sqrt{N}\),避免无意义的枚举
    • 适用于"小规模整数拆分 + 低维枚举"类问题,核心是确定枚举范围后直接暴力

【解题思路】

【算法标签】

普及- #模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, ans=0;
int main()
{
    cin >> n;  // 输入n
    for (int i=0; i<=100; i++) {  // 因为选取4块草皮,所以4层for循环暴力枚举
        for (int j=0; j<=100; j++) {
            for (int k=0; k<=100; k++) {
                for (int l=0; l<=100; l++) {
                    if (i*i+j*j+k*k+l*l==n) {  // 当4个草皮中方格的面积之和等于n时
                        ans++;  // 方案数加1
                    }
                }
            }
        }
    }
    cout << ans << endl;  // 打印结果
    return 0;
}

【运行结果】

4
5
posted @ 2026-08-28 15:54  团爸讲算法  阅读(3)  评论(0)    收藏  举报