zoukankan      html  css  js  c++  java
  • CF1304C Air Conditioner

    题外话

    这道题……

    一道黄题。

    一道简单的思维题。

    题意简述

    题目链接

    有一个量,初始为m,每单位时间可将其+1或-1或不变。现有n个三元组(t,l,r),要求且仅要求在t时刻该量的值需要在区间[l,r]内,问是否能满足这n个三元组的要求。

    算法概述

    数据中n个三元组都是按t的顺序给出的,所以无需我们自行排序。

    首先考虑第一个三元组如何满足,可以启发我们如何去判断后面的三元组。

    初始为0时刻值为m,第一个要求是t时刻在[l,r]内,我们可以考虑从0到t这段时间内,我们所能变化到的值域区间是[m-t,m+t],那么只需考虑[l,r]与[m-t,m+t]是否有交即可,然后这一时刻的取值范围即为这个交集区间。

    然后考虑推广。在第i个三元组时,即ti时刻,当前的取值范围假设为[L,R],第i+1个三元组的要求是在ti+1时刻,需要在区间[li+1,ri+1]内,那么我们设d=ti+1-ti,则我们所能变化到的值域区间即为[L-d,R+d],那么ti+1时刻的取值范围即为[L-d,R+d]与[li+1,ri+1]的交集。

    如此,我们便得到了一个很好的可以解决该问题的算法:

    初始的取值范围为[m,m],然后依次遍历n个三元组,对于每个三元组,根据t计算出与上一个三元组的时间差d,然后通过上一个取值范围[L,R]计算出当前所能达到的值域区间[L-d,R+d],然后将这个值域区间与当前三元组的要求范围[l,r]取交集即为新的取值范围。

    无解的情况则只需看在过程中,每次取交集时,取出的交集区间是否合法即可。也就是说,每次需要取交集时,若出现没有交集的情况,即为无解。

    至于区间求交的方法,假设有两个区间[l1,r1],[l2,r2],两者的交集即为[max(l1,l2),min(r1,r2)],合法条件是max(l1,l2)<=min(r1,r2)。

    参考代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=110;
    int l[N],r[N],t[N];
    int T,n,t0;
    
    void get_inter(int l1,int r1,int l2,int r2,int &ans_l,int &ans_r)
    {
    	ans_l=max(l1,l2);
    	ans_r=min(r1,r2);
    } 
    
    int main()
    {
    	scanf("%d",&T);
    	while(T--)
    	{
    		scanf("%d%d",&n,&t0);
    		int L=t0,R=t0,flag=1;
    		for(int i=1;i<=n;i++)
    			scanf("%d%d%d",&t[i],&l[i],&r[i]);
    		for(int i=1;i<=n;i++)
    		{
    			int dlt=t[i]-t[i-1];
    			int l1=L-dlt,r1=R+dlt;
    			get_inter(l1,r1,l[i],r[i],L,R);
    			if(L>R)
    			{
    				flag=0;
    				break;
    			} 
    		}
    		if(flag)printf("YES
    ");
    		else printf("NO
    ");
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Python
    python参数传递方式
    python可变类型和不可变类型
    进程、线程和协程的理解
    cookie原理
    http报文格式
    Charles的HTTPS抓包方法及原理分析
    fiddler抓包https请求
    python正则表达式
    java的Junit单元测试
  • 原文地址:https://www.cnblogs.com/ninedream/p/13540817.html
Copyright © 2011-2022 走看看