1. 题目背景与问题分析
2007年10月USACO白银组的这道题目《Bessie's Secret Pasture》看似简单,实则蕴含了组合数学和暴力枚举的经典思想。题目描述了一个有趣的场景:农场主John有无限多块正方形牧草,Bessie需要从中选取四块来填满她牧场上的N个格子。
关键点在于理解题目要求:我们需要找出所有四个非负整数的平方和等于N的组合。这里的"组合"指的是有序元组,即(1,2,3,4)和(4,3,2,1)被视为不同的方案。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解题思路详解
2.1 暴力枚举法
最直观的解法就是四重循环暴力枚举所有可能的组合:
cpp复制for (int i=0; i*i<=n; i++) {
for (int j=0; j*j<=n; j++) {
for (int k=0; k*k<=n; k++) {
for (int l=0; l*l<=n; l++) {
if (i*i + j*j + k*k + l*l == n) {
ans++;
}
}
}
}
}
这种方法的优点是简单直接,容易理解和实现。但缺点也很明显:时间复杂度为O(n²),当n较大时效率会很低。
2.2 优化思路
我们可以从几个方面进行优化:
-
循环边界优化:每层循环只需要遍历到√n即可,因为超过√n的数的平方已经大于n了。
-
提前终止:在内层循环中,如果前三项的平方和已经大于n,可以直接跳过当前循环。
-
记忆化搜索:可以预先计算所有可能的平方数,然后使用动态规划或记忆化搜索来减少重复计算。
3. 代码实现与解析
3.1 基础实现
cpp复制#include <iostream>
#include <cmath>
using namespace std;
int main() {
int n, ans = 0;
cin >> n;
int max_val = sqrt(n) + 1; // 确定最大可能的边长
for
