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;
}