4.25 每日一题题解

二元

涉及知识点:

  • 排序/优先队列

solution:

  • (周末啦,美好的一天要从刷题开始~)
  • (题意是让我们找到k个二元组,要求最小的a和最小的b最大)
  • (直接遍历,两个值都有可能变大变小,考虑先将数组根据a从小到大排序)
  • (二元组排为按a降序,则当前i的a即为最小的a)
  • (遍历数组,将b的值放到优先队列(小根堆)里)
  • (当优先队列大小第一次等于k时,A[i].a即为k组二元组中最小的a)
  • (因为i往后循环a的值只会越来越小(或不变),再加上q队头的元素b即为k组a+b的最小值)
  • (下一组最优解(如果有)一定是a小于当前最优解的a,而b大于当前最优解的b)
  • (因为当前最优解的b一定已被弹出,即当队列的大小大于k时,将队头元素弹出。)
  • (如果不熟悉优先队列建议先了解一下优先队列,很好用的!)

std:

#include <bits/stdc++.h>
using namespace std;
#define ll long long 
const int maxn = 100005;
struct node{
    int a,b;
}A[maxn];
bool cmp(node p1,node p2){
    return p1.a > p2.a;
}

int main()
{
    int n , k , ans = 0;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
        cin>>A[i].a>>A[i].b;
    sort(A+1,A+1+n,cmp);
    priority_queue< int,vector<int>,greater<int> > q;
    
    for(int i=1;i<=n;i++){
        q.push(A[i].b);
        if(q.size() > k){
            q.pop();
        }
        if(q.size() == k){
            ans = max(ans , q.top()+A[i].a);
        }
    }
    cout<<ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/QFNU-ACM/p/12771414.html