• [CSP-S模拟测试]:时间机器(贪心+set)


    题目描述

      作为一名天才科学家,$Kurisu$已经设计出了时间机器的构造。
      根据$Kurisu$的构想,时间机器中有$n$种需要放置电阻的节点,第$i$种节点有$s_i$个,其电压$U$的变动范围是${low}_ileqslant Uleqslant {high}_i$。
      现在有$m$种电阻,第$i$种电阻有$k_i$个,第$i$种电阻能正常工作时,电压$U'$需要满足$l_ileqslant U'leqslant r_i$。第$i$种电阻能放置在第$j$种节点上,当且仅当$l_ileqslant {low}_jleqslant {high}_jleqslant r_i$。
      现在$Kurisu$想要确认她的构想能不能实现,即是否能在所有节点上放置合适的电阻。


    输入格式

    第一行一个整数$T$,表示数据组数。
    每组数据的第一行有两个整数$n,m$,表示节点和电阻的种类数。
    接下来$n$行,每行三个整数${low}_i,{high}_i,s_i$,描述一种结点。
    接下来$m$行,每行三个整数$l_i,r_i,k_i$,描述一种电阻。


    输出格式

    输出共$T$行,每行一个字符串,若可以实现则输出$"Yes"$(不包含引号),否则输出$"No"$。


    样例

    样例输入:

    3
    2 2
    1 4 2
    3 5 1
    1 4 2
    2 5 1
    3 2
    1 3 1
    2 4 1
    3 5 1
    1 3 2
    2 5 1
    2 2
    1 2 2
    1 2 1
    1 2 1
    1 2 2

    样例输出:

    Yes
    No
    Yes


    数据范围与提示

    保证$1leqslant {low}_ileqslant {high}_ileqslant {10}^9,1leqslant l_ileqslant r_ileqslant {10}^9,1leqslant k_i,s_ileqslant {10}^9,Tleqslant 50,1leqslant n,mleqslant 5 imes {10}^4$。
    记$sum n$为一个测试点中所有$n$的总和,记$sum m$为一个测试点中所有$m$的总和,则$sum n,sum mleqslant 4 imes {10}^5$。
    各个测试点还满足如下约束:


    题解

    考虑贪心。

    将电阻个节点均按左端点排序,按排序考虑每一种节点,每次贪心地选择左端点在该节点左侧的电阻中,右端点在该节点右侧且尽量靠近该节点右侧的电阻。

    考虑如何优化。

    利用$set$维护当前左端点符合条件的电阻的右端点即可。

    时间复杂度:$Theta((n+m)log m+nlog n)$。

    期望得分:$100$分。

    实际得分:$100$分。


    数据范围

    #include<bits/stdc++.h>
    using namespace std;
    struct rec{int l,r,s;}a[50001],b[50001];
    struct node{int first,second;};
    int n,m;
    set<node> s;
    bool cmp(rec a,rec b){return a.l<b.l;}
    bool operator < (node a,node b){return a.first<b.first;}
    int main()
    {
    	int T;scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&m);
    		s.clear();
    		for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].s);
    		for(int i=1;i<=m;i++)scanf("%d%d%d",&b[i].l,&b[i].r,&b[i].s);
    		sort(a+1,a+n+1,cmp);
    		sort(b+1,b+m+1,cmp);
    		s.insert((node){2002092300,0});
    		for(int i=1,j=1;i<=n;i++)
    		{
    			while(b[j].l<=a[i].l&&j<=m)
    				s.insert((node){b[j].r,j++});
    			node flag=(node){a[i].r,0};
    			while(a[i].s)
    			{
    				flag=*s.upper_bound(flag);
    				if(flag.first==2002092300)break;
    				int t=min(b[flag.second].s,a[i].s);
    				b[flag.second].s-=t;a[i].s-=t;
    				if(!b[flag.second].s)s.erase(flag);
    			}
    			if(a[i].s){puts("No");goto nxt;}
    		}
    		puts("Yes");
    		nxt:;
    	}
    	return 0;
    }
    

    rp++

  • 相关阅读:
    __attribute__ 总结
    linux文件夹打包命令
    学习ARM的一些基本知识,个人整理
    备忘录之 —— .bashrc(IC工具篇)
    GitHub的基本使用
    02: SocketServer服务
    01: socket模块
    08: python基础练习题
    07: 高阶函数&异常处理
    06: 面向对象
  • 原文地址:https://www.cnblogs.com/wzc521/p/11535584.html
Copyright © 2020-2023  润新知