Codeforces Round #653 (Div. 3) E1. Reading Books (easy version) 题解(模拟)
题目链接
题目大意
给你n本数,俩个人对这n本书有的喜欢,有的讨厌,现在问,这俩个人分别从他们喜欢的书中挑k本出来(如果挑不出来,输出-1),现在问每本书的最少阅读时间的总和为多少?
题目思路
emmmm,我还以为要用优先队列啥的,没想到居然就是直接模拟一下就行了。
1.我们开三个数组分别存储:俩个小孩都喜欢的书,第一个小孩喜欢的书,第二个小孩喜欢的书的所需要看的时间。
2.再把时间从小到大排序,然后再分情况:
(1)如果有一个人不能选k本书出来看,那么直接输出-1
(2)如果俩个人都喜欢的书的花费时间 大于 第一个小孩喜欢的书的时间加上第二个小孩喜欢的书的时间(书按照现在最短的那个时间依次推),那么我们肯定是选择时间少的那种,然后把这俩本书删除,再判断。
(3)与第二种情况相反,那么我们就选择俩个人都喜欢的书,然后把这本书删除,即可
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
const int mod=1e9+7;
int n,k,a1[maxn],a2[maxn],a3[maxn],num1,num2,num3;
int main(){
scanf("%d%d",&n,&k);
for(int i=1,t,a,b;i<=n;i++){
scanf("%d%d%d",&t,&a,&b);
if(a&&b){
a1[++num1]=t;
}else if(a&&(!b)){
a2[++num2]=t;
}else if((!a)&&b){
a3[++num3]=t;
}
}
sort(a1+1,a1+1+num1);
sort(a2+1,a2+1+num2);
sort(a3+1,a3+1+num3);
if(num1+min(num2,num3)<k){
//如果有人不能选k本书,那么直接输出-1
printf("-1\n");
}else{
int pos1=1,pos2=1,sum=0;
while(pos1+pos2-2<k){
if(pos1>num1){
//如果俩个人都喜欢的书已经没有了,那么肯定只能分开选书了
sum+=a2[pos2]+a3[pos2];
pos2++;
}else if(pos2<=min(num2,num3)&&a1[pos1]>=a2[pos2]+a3[pos2]){
//前提是他们还有俩本书可以选
sum+=a2[pos2]+a3[pos2];
pos2++;
}else{
//否则就是俩个人都喜欢的书的花费时间小于分开选书
sum+=a1[pos1];
pos1++;
}
}
printf("%d\n",sum);
}
return 0;
}