GESP2026年3月认证C++五级( 第三部分编程题(2)找数)


🌟 题目:找数(两个数组交集)


🧠 一、故事:两支探险队 🧭

有两支探险队:

  • 🟦 A队:有 n 个宝藏

  • 🟥 B队:有 m 个宝藏

👉 每个宝藏都有一个编号(整数)


👑 国王说:

"统计一下,有多少宝藏同时出现在 A队 和 B队!"


🌟 二、问题本质(非常重要!)

👉 就是:

复制代码
求两个数组的"交集个数"

🌟 三、最简单理解(暴力方法)


❌方法1:双重循环

复制代码
for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
        if(a[i] == b[j]) ans++;

❗问题:

👉 时间复杂度:

复制代码
O(n × m)

👉 太慢!(考试会超时)


🌟 四、聪明方法(二分查找🔥)


🧠故事:图书馆找书 📚

A队的书已经整理好了(排序)

👉 想找一本书:

👉 用"二分查找"!


🌟 五、核心思路(必须掌握!)


🎯步骤:

1️⃣ 先排序 A

复制代码
sort(a.begin(), a.end());

2️⃣ 遍历 B

对每个 b:

👉 去 A 里面找!


3️⃣ 用二分查找


🌟 六、二分查找详解(重点🔥)


1、🧠故事:猜数字游戏 🎯

你要找一个数:

复制代码
l = 0, r = n-1

2✨每次:

复制代码
mid = (l + r) / 2

3、判断:

复制代码
if(a[mid] > b)  r = mid - 1;
else if(a[mid] < b) l = mid + 1;
else 找到了!

🌟 七、完整代码

复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;

    vector<int> a(n);

    // 输入 A
    for(int i = 0; i < n; i++)
        cin >> a[i];

    // 排序 A(非常关键!)
    sort(a.begin(), a.end());

    int ans = 0;

    // 遍历 B
    for(int i = 0, b; i < m; i++) {
        cin >> b;

        int l = 0, r = n - 1;
        bool ok = false;

        // 二分查找
        while(l <= r) {
            int mid = (l + r) / 2;

            if(a[mid] > b)
                r = mid - 1;
            else if(a[mid] < b)
                l = mid + 1;
            else {
                ok = true;
                break;
            }
        }

        if(ok) ans++;
    }

    cout << ans << endl;

    return 0;
}

🌟 八、举个例子


1、🌰输入:

复制代码
A = [4, 2, 3]
B = [3, 1, 5, 4, 6]

2、✨步骤:

排序 A:

复制代码
A = [2, 3, 4]

3、遍历 B:

  • 找 3 ✔️

  • 找 1 ❌

  • 找 5 ❌

  • 找 4 ✔️

  • 找 6 ❌


4、👉 总共:

复制代码
2 个

🌟 九、复杂度分析


⏱ 时间复杂度:

  • 排序:O(n log n)

  • 查找:m × O(log n)


👉 总:

复制代码
O(n log n + m log n)

🌟 十、进阶技巧(高手必备🔥)


🎯方法2:双指针(更快)

1、👉 如果两个数组都排序:

复制代码
i 指向 A
j 指向 B

2、同时移动:

复制代码
A[i] == B[j] → ans++
A[i] < B[j] → i++
A[i] > B[j] → j++

3、👉 时间复杂度:

复制代码
O(n + m)

🌟 十一、总结


🎯这类题本质:

👉 查找 + 优化


🎯多种解法比较:

方法 复杂度 推荐
暴力 O(nm)
二分 O(m log n) ✔️
双指针 O(n+m) ⭐⭐⭐

🌟 十二、考点回顾:

我们必须掌握:


1️⃣ 二分查找模板(超级重点🔥)

复制代码
while(l <= r){
    mid = (l + r)/2;
    if(a[mid] > x) r = mid - 1;
    else if(a[mid] < x) l = mid + 1;
    else return true;
}

2️⃣ 排序 + 查找组合思维

👉 GESP五级考试很多题都是:

复制代码
排序 + 二分

相关推荐
我头发多我先学4 分钟前
C++ 红黑树:从规则到实现,手把手带你写一棵红黑树
数据结构·c++·算法
lzh2004091911 分钟前
深入学习Linux进程间通信:解析消息队列
linux·c++
水饺编程20 分钟前
第5章,[标签 Win32] :设备的尺寸(三)
c语言·c++·windows·visual studio
Cando学算法21 分钟前
中位数定理:到所有点的距离之和最小的点就是中位数
c++·算法·学习方法
HZY1618yzh31 分钟前
洛谷题解:P16304 [蓝桥杯 2026 省 Java C 组] 抽奖活动
java·c++·算法·蓝桥杯
智者知已应修善业44 分钟前
【51单片机从奇数始再转偶数逐一点亮并循环】2023-9-8
c++·经验分享·笔记·算法·51单片机
努力努力再努力wz1 小时前
【MySQL进阶系列】拒绝冗余SQL:带你透彻理解视图的底层逻辑
android·c语言·数据结构·数据库·c++·sql·mysql
Yupureki1 小时前
《Linux网络编程》4.应用层HTTP协议
linux·服务器·c语言·网络·c++·http
Brilliantwxx1 小时前
【C++】认识vector(概念+题目OJ)
开发语言·c++·笔记·算法
上弦月-编程2 小时前
C语言链表详解,新手也能看懂! ——从入门到精通的完整教程
java·c语言·c++