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\n");
		else printf("NO\n");
	}
	return 0;
}

  

posted @ 2020-08-21 14:22  魑吻丶殇之玖梦  阅读(209)  评论(0编辑  收藏  举报