题解-和数

题目描述
给定一个正整数序列,判断其中有多少个数,等于数列中其他两个数的和。 比如,对于数列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

  1. 枚举所有可能的两个数的和(使用双重循环)
  2. 检查这个和是否在原始数列中出现(可以用哈希表或排序 + 二分查找)

注意

  • 同一个数字不能重复使用(但不同位置可以用同一个值)
  • 所得和不能来自当前要匹配的目标数字本身

✅ 解法一:排序 + 暴力枚举 + 存在性判断

#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)}
]
做法如下:

  1. 将数组排序
  2. 对每一对不同的数 ( a[i] + a[j] )(( i < j )),在数组中用二分查找查找这个和是否存在
  3. 如果找到了这个和,且该值不等于 ( a[i] ) 或 ( a[j] ) 本身的索引位置,就计数
  4. 用一个布尔数组 vis[] 标记某个值是否已经计数过,避免重复计数
#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 数组 判断是否已经计数过某个数;
  • 二分查找 可用于更大数据时优化查找效率。
posted @ 2025-07-19 10:48  stephen_zuo  阅读(23)  评论(0)    收藏  举报