题解:
–这道题其实是 贪心 吧,我们先来分析一波:
1.对于每个s和t,一定有(s-t)个人被甲选了,却没有被乙选上,而他们没有被选上的原因是:y值比那t个被选中的人的y的最小值还要小,或是y值相等时x太大
2.假设我们要让一个(x1,y1)的人被乙选上,那么那(s-t)个人的y值都要比y1小,或是与y1相等,x比x1大
3.所以说如果比某个人的y值小(或是y值相等时x比他大)的人数不足(s-t)个的话,他是显然不可能被乙选上的
–现在我们就可以先把必定不可能的人标记出来,再让甲选t个可能被乙选中且x值最大的前t个人,最后找(s-t)个满足条件的人充数就行了
–我们就可以用强大的sort
来解决问题了,啦啦啦
代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXN=1e5+5;
int n,s,t;
int x[MAXN],y[MAXN];
int sx[MAXN],sy[MAXN],S[MAXN];
bool no[MAXN],choose[MAXN];
long long ansx,ansy;
bool comp1(const int &a,const int &b){
if(x[a]!=x[b])
return x[a]>x[b];
return y[a]>y[b];
}
bool comp2(const int &a,const int &b){
if(y[a]!=y[b])
return y[a]>y[b];
return x[a]<x[b];
}
bool comp3(const int &a,const int &b){
if(no[a]!=no[b])
return no[a];
if(y[a]!=y[b])
return y[a]>y[b];
return x[a]>x[b];
}
int main(){
cin>>n>>s>>t;
for(int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
sx[i]=i;
sy[i]=i;
S[i]=i;
}
sort(sx+1,sx+1+n,comp1);
sort(sy+1,sy+1+n,comp2);
for(int i=n;i>=n-(s-t)+1;i--)
no[sy[i]]=1;
int sum=0;
for(int i=1;i<=n;i++){
if(!no[sx[i]]){
choose[sx[i]]=1;
sum++;
if(sum==t)
break;
}
}
for(int i=n;i>=1;i--){
if(choose[sy[i]])
break;
else
no[sy[i]]=1;
}
sort(S+1,S+1+n,comp3);
for(int i=1;i<=s-t;i++)
choose[S[i]]=1;
for(int i=1;i<=n;i++){
if(choose[i]){
ansx+=x[i];
ansy+=y[i];
}
}
cout<<ansx<<" "<<ansy;
return 0;
}