1 条题解

  • 0
    @ 2025-8-24 21:42:29

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar zac2010
    a vegedog

    搬运于2025-08-24 21:42:29,当前版本为作者最后更新于2022-03-26 14:53:06,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    这道题目是溢水的蓝题(毕竟用 multiset 做就是如此)!!

    思路

    这道题我们通过排序来削掉口感那个指标!

    首先,我们定义一个结构体(方便排序)

    struct A{
    	int a,b,c;//a、b为题目中的意思,c=0表示当前的为牛,相反,c=1表示当前的为干草
    }a[200010];
    
    

    再定义一个可重集 multiset

    multiset<int>s;
    

    所以我们先把草和牛按照口感从大到小排序

    bool cmp(A a,A b){
    	if(a.b==b.b)
    		return a.c>b.c;
    	return a.b>b.b;
    }
    sort(a+1,a+n+1,cmp);
    

    我们再从前往后遍历排序后的数组

    1. 如果遇到了草,我们把它的价钱加进 multiset
    if(a[i].c==1)
    	s.insert(a[i].a);
    
    1. 如果遇到了牛,由于我们的第二个指标也就是口感满足一定大于等于当前牛的口感,所以不用管,毕竟我们已经排过序了(成功削掉一个指标)。然后我们呢再通过 multiset 的一系列操作得到最小的大于等于当前所需价钱的干草。
    else{
    	set<int>::iterator it=s.lower_bound(a[i].a);
    	if(s.empty()||it==s.end()){
    		cout<<-1<<endl;
    		return 0;
    	}
    	ans+=*it;
    	s.erase(it);
    }
    
    

    最后输出所有干草价钱的和即可

    代码

    #include <bits/stdc++.h>
    #define int long long
    using namespace std;
    struct A{
    	int a,b,c;
    }a[200010];
    int n,m,ans;
    multiset<int>s;
    bool cmp(A a,A b){
    	if(a.b==b.b)
    		return a.c>b.c;
    	return a.b>b.b;
    }
    signed main(){
    	scanf("%lld%lld",&n,&m);
    	for(int i=1;i<=n;i++){
    		scanf("%lld%lld",&a[i].a,&a[i].b);
    		a[i].c=0;
    	}
    	n+=m;
    	for(int i=n-m+1;i<=n;i++){
    		scanf("%lld%lld",&a[i].a,&a[i].b);
    		a[i].c=1;
    	}
    	sort(a+1,a+n+1,cmp);
    	for(int i=1;i<=n;i++){
    		if(a[i].c==1)
    			s.insert(a[i].a);
    		else{
    			set<int>::iterator it=s.lower_bound(a[i].a);
    			if(s.empty()||it==s.end()){
    				cout<<-1<<endl;
    				return 0;
    			}
    			ans+=*it;
    			s.erase(it);
    		}
    	}
    	cout<<ans<<endl;
    }
    
    • 1

    信息

    ID
    1934
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者