#19272. 神奇的平方差
神奇的平方差
你好!我是你的OI金牌教练。
上一题我们练习了勾股定理(),这次我们利用另一个初中代数核心公式——平方差公式(),设计一道新的GESP 4级难度题目。
这道题考察的重点是循环结构的运用、数学边界条件的分析以及简单的时间复杂度估算。
题目名称:神奇的平方差 (Difference of Squares)
题目描述
在初中数学代数课上,小杨学习了著名的平方差公式:。
老师告诉小杨,对于给定的一个正整数 ,可能存在多对正整数 ,满足它们的平方之差恰好等于 ,即 。
例如,当 时:
- ,所以 是一组解。
- ,所以 是一组解。
现在请你编写程序,输入一个正整数 ,计算出共有多少对正整数 满足 。
输入格式
输入一行,包含一个正整数 。
输出格式
输出一行,一个整数,表示满足条件的正整数对 的数量。
输入输出样例 #1
输入:
15
输出:
2
输入输出样例 #2
输入:
24
输出:
2
解释:满足 的正整数对有 和 。
输入输出样例 #3
输入:
10
输出:
0
解释:不存在正整数 使得 。
数据范围
对于 的数据,保证 。
题目分析与思路提示
作为教练,我来带你在草稿纸上分析这道题,避免盲目写代码。
1. 读题关键词
- “”:这是核心等式。
- “正整数”:。
- “数量”:只需要输出个数,不需要输出具体的 和 。
- 数据范围 :范围很小,我们可以尝试枚举法。
2. 启发式思考过程(草稿纸推演)
思路一:双重循环枚举(暴力法) 能不能像上一题一样枚举 和 ?
- 一定比 大(因为 是正数)。
- 最大可能是多少?
- 考虑 最小为 1。此时 。
- 等等,这个思路不对!
- 看样例 ,解有 。此时 ,而 。这说明 可以比 大得多。
- 我们看最极端的情况: 和 挨得很近,即 。
- 此时 $(y+1)^2 - y^2 = M \Rightarrow 2y + 1 = M \Rightarrow y = (M-1)/2$。
- 如果 ,那么 大约是 1000, 也是 1000 左右。
- 结论:如果枚举 和 ,范围都要到 左右。两层循环大概是 次运算。完全可行!
思路二:单层循环枚举(优化解法) 既然 ,那么 。 我们只需要枚举 ,算出 ,然后判断这个结果是不是完全平方数。 如果是,说明找到了对应的 ,计数器加 1。
- 的枚举范围是多少?
- 我们知道 ,最小的差距是 。
- 此时 。
- 因为 ,所以 。
- 推导出 。
- 当 时, 只需要循环到 999。运算量只有 1000 次,非常快!
3. 草稿纸上的模拟(以 M=24 为例)
目标:,且 为整数。 枚举 :
- : 。,是整数。✅ 找到一组 (5, 1)
- : 。,不是整数。❌
- : 。不是完全平方数。❌
- : 。不是。❌
- : 。,是整数。✅ 找到一组 (7, 5)
- : 。不是。
- : 。不是。
- ... 还要继续吗?
- 根据公式 。枚举到 11 即可停止。
参考代码实现 (C++14)
/**
* 题目:神奇的平方差
* 难度:GESP 4级
* 算法:枚举 (Enumerate)
*/
#include <iostream>
#include <cmath> // 必须包含,用于 sqrt
using namespace std;
int main() {
// 1. 输入 M
int M;
if (!(cin >> M)) return 0;
int ans = 0;
// 2. 循环枚举 y
// 根据数学推导,y 的上限是 (M - 1) / 2
// 如果不会推导,直接让 y 循环到 M 也可以,因为 M <= 2000,不会超时
for (int y = 1; y <= (M - 1) / 2; ++y) {
// 计算 x^2 应该是多少
long long x_sq = 1LL * M + 1LL * y * y; // 使用 long long 防止溢出(虽然M=2000时int够用)
// 计算 x
int x = sqrt(x_sq);
// 3. 检查 x 是否是整数 (完全平方数判断)
// 也就是看算出来的 x 平方回去是否等于 x_sq
if (1LL * x * x == x_sq) {
ans++;
// 调试输出(提交时建议注释掉):
// cout << "Found: x=" << x << ", y=" << y << endl;
}
}
// 4. 输出结果
cout << ans << endl;
return 0;
}
考点总结与复杂度分析
- 时间复杂度:。最坏循环约 次。对于 ,计算量忽略不计。即使 ,这种做法也是勉强能接受的(1秒以内)。
- 空间复杂度:。
- 初中数学联系:
- 理解 的增长关系。
- 如果不使用枚举,这道题其实等价于分解因数:,令 ,解方程组得 。这要求 同奇偶。这是更高级的 解法,但对于 GESP 4级,枚举法是更标准、更易写的解法。
快去动手试试吧!