福建OJ——虚拟世界

题目链接


题目描述

有一天你无意中进入了一个虚拟世界,经过几天的探索你找到了回到现实世界的办法。为此你需要找到两个人帮你打开一个神奇的机关,条件是这两个人的年龄之和正好等于某个神秘数字。于是,你找来了n个人,想试一下他们中是否有2个人的年龄之和等于神秘的数字m。
请你写一个程序来找出其中这2个人。


输入数据

共三行:
第一行是整数n(0 < n <= 100000),表示你找来了n个人。
第二行是n个整数,表示每个人的年龄,整数的范围是在0到10^8之间(没错,他们很长寿)。
第三行是一个整数m(0 < m <= 2^30),表示机关中的神秘数字。


输出格式

如果能找出这样的两个人,输出他们的年龄,小的在前,大的在后,中间用单个空格隔开;
如果有多种情况满足条件,输出两人中年轻人年龄最小的那种情况;
若找不到符合要求的两个人,输出一行No。


样例数据

【输入样例1】

10
10486 7849 9064 6613 17924 31429 14728 2905 15369 1599
21341

【输出样例1】

6613 14728

【输入样例2】

15
18955 25668 29677 12514 24928 22593 24386 14659 2147 17676 3232 2600 28148 25050 19196
20

【输出样例2】

No

解题思路

这道题就是求数列中有没有两个数之和等于m,如果有,就输出年龄最小的情况,否则输出“No”。

如果用常规的暴力搜索:

    for (int i = 1 ; i < n ; i ++){
        for (int j = i + 1 ; j <= n ; j ++){
            if (a[i] + a[j] == m){
                cout << a[i] << " " << a[j];
                return 0;
            }
        }
    }
    cout << "No" << endl;
    return 0;

时间复杂度为O(n²),而这里的n≤100000,n²≤ 100000²,远远超过了10⁸,会超时。所以这种做法不可取。

那还有什么方法呢?

通过观察,我们发现在一个无序数组中查找两个数的和需要O(n²)的时间复杂度,但是在有序数组中我们只需要O(n)就可以了。所以可以先把无序数组通过快速排序转换成有序数组,再通过O(n)来查找。

时间复杂度:

快速排序: O(N log N)

顺序查找:O(N)

总共:O(N log N)。


代码实现

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
long long m, n, a[N];
int main() {
    freopen("world.in", "r", stdin);
    freopen("world.out", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }
    cin >> m;
    sort(a, a + n);
    for (int i = 0, j = n - 1; i < j;) {
        if (a[i] + a[j] == m) {
            cout << a[i] << " " << a[j];
            return 0;
        } else if (a[i] + a[j] < m)
            i++;
        else
            j--;
    }
    cout << "No" << endl;
    return 0;
}

不喜勿喷(bushi)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值