【贪心】2020牛客寒假算法基础集训营 A题

2020牛客寒假算法基础集训营 A题:配对
链接:https://ac.nowcoder.com/acm/contest/3007/A
来源:牛客网

题目描述
现在有正整数集合 A 和 B,每个集合里有 N 个数,你要建立他们间的一一映射
将每对配对的数字相加可以得到 N 个和,你要做的就是最大化第 K 大的和
1≤K≤N≤100,000 输入的所有数字不超过 10^8

输入描述:
第一行 2 个数字 N,K
接下来两行,每行 N 个正整数,分别表示 A 和 B 中的元素

输出描述:
一行,表示第 K 大的和的最大值

示例
输入
3 2
1 2 3
1 2 3

输出
5

比赛时的想法:
能够隐约感觉到这是一道贪心的题目,但是问题是如何贪?
差不多花了半个小时在找规律,然后放弃了。
摸不清楚到底如何使得第k个数字最大。
因为一一映射会有n!个组合 啊 想想就头大

题解思路:
因为是求第k大,所以肯定是数组a与数组b中各自的前k大的数产生。
但光想出这个还不行,还是k!个组合。
这个时候再想想,不就是找第k大的和么,肯定不能大与大小与小组合了,不然排到最后第k个数就变成所有组合里面的最小了;一大一小这样的组合才能让第k个和尽可能地大。
所以得出结论,倒序配对最优。
在a数组和b数组的最大的前k个数里,采取a最小-b最大,a第二小-b第二大,这样的一种组合方式,然后找到这个组合里的最小的值,即为k值。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
 
int a[N], b[N], n, k, ans = 0x3f3f3f3f;
int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &a[i]);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &b[i]);
    sort(a + 1, a + n + 1);
    sort(b + 1, b + n + 1);
    for(int i = n; i > n - k; i --)
        ans = min(ans, a[i] + b[n - i + n - k + 1]);
    printf("%d\n", ans);
    return 0;
}

做题感悟:

做题少,无从下手

发布了16 篇原创文章 · 获赞 0 · 访问量 116

猜你喜欢

转载自blog.csdn.net/weixin_44745441/article/details/104364408