题解-和数
题目描述
给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列1 2 3 4, 这个问题的答案就是2, 因为3 = 2 + 1, 4 = 1 + 3。
输入格式
共两行,第一行是数列中数的个数n ( 1 <= n <= 100),第二行是由n个不大于10000的正整数组成的数列,相邻两个整数之间用单个空格隔开。
输出格式
一个整数,即数列中等于其他两个数之和的数的个数。
样例
输入样例
4
1 2 3 4
Copy
输出样例
2
解题思路
💡 解题思路1
我们要找出序列中有多少个元素,等于两个不同数的和。
暴力解法思路1
- 枚举所有可能的两个数的和(使用双重循环)
- 检查这个和是否在原始数列中出现(可以用哈希表或排序 + 二分查找)
注意
- 同一个数字不能重复使用(但不同位置可以用同一个值)
- 所得和不能来自当前要匹配的目标数字本身
✅ 解法一:排序 + 暴力枚举 + 存在性判断
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int a[105];
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a, a + n);
int count = 0;
for (int i = 0; i < n; ++i) {
bool found = false; // 用来标记是否已经找到匹配
for (int j = 0; j < n && !found; ++j) {
for (int k = j + 1; k < n; ++k) {
if (i != j && i != k && a[j] + a[k] == a[i]) {
count++;
found = true; // 设置标记
break; // 跳出最内层循环
}
}
}
}
cout << count << endl;
return 0;
}
题解:判断数列中有多少个数是其他两个数之和(使用二分查找)
解题思路:排序 + 二分查找
💡 解题思路:排序 + 二分查找
我们希望判断数组中是否存在某个数 ( x ),使得:
[
x = a[i] + a[j] \quad \text{(i ≠ j)}
]
做法如下:
- 将数组排序;
- 对每一对不同的数 ( a[i] + a[j] )(( i < j )),在数组中用二分查找查找这个和是否存在;
- 如果找到了这个和,且该值不等于 ( a[i] ) 或 ( a[j] ) 本身的索引位置,就计数;
- 用一个布尔数组
vis[]标记某个值是否已经计数过,避免重复计数。
✅ C++ 代码(使用 binary_search)
#include <iostream>
#include <algorithm>
using namespace std;
int a[105];
bool vis[20005]; // 标记某个值是否已经计数过
int main() {
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
sort(a, a + n);
int count = 0;
for (int i = 0; i < n; ++i) {
// 枚举两两之和 a[j] + a[k]
for (int j = 0; j < n; ++j) {
if (i == j) continue;
for (int k = j + 1; k < n; ++k) {
if (i == k) continue;
int sum = a[j] + a[k];
if (sum == a[i] && !vis[a[i]]) {
vis[a[i]] = true; // 标记已统计
count++;
break; // 当前 a[i] 满足即可,无需再找其他组合
}
}
}
}
cout << count << endl;
return 0;
}
📈 时间复杂度分析
- 排序:(O(n \log n))
- 枚举所有两数组合:(O(n^2))
- 查找是否为某元素:(O(1))(因为我们不再查找,而是直接与数组元素对比)
整体时间复杂度约为 (O(n^2)),对于 (n \leq 100),是可以接受的。
🧠 小结
- 学会使用 二重循环枚举两数之和;
- 使用 排序 +
vis数组 判断是否已经计数过某个数; - 二分查找 可用于更大数据时优化查找效率。

浙公网安备 33010602011771号