原题:https://fjnuacm.top/d/junior/p/P1304C空调凉凉~
题意
一个餐馆中有个空调,给定空调的初始温度为 \(m\),每分钟可以选择上调或下调 \(1\) 个单位的温度,或选择不变。
给定 \(n\) 个食客的到达时间 \(t_i\) 以及所能适应的温度范围 \([l_i, r_i]\),每个食客只会在 \(t_i\) 时刻逗留。
如果温度不在食客的适应范围内,他就会不舒服。输出空调能否使得所有食客都感到舒服。
思路
当初第一反应是维护一个温度值,根据食客的需求改变温度。但这里存在问题:对于有限的操作,最后能落在温度区间的温度是不唯一的。如果是这样,很多种可能叠加,不难发现会超时。
也许我们可以贪心地认为只要满足最低条件即可,但我们不能保证下一个本因可行的区间可能被判为不可行(如一直递增的温度区间)。
单个值失败了,那就多个值呗。
我们只要维护一个区间,让每次所有的可行解落在该区间。然后,对于每一个区间,将其与后面的区间进行区间重叠运算。
对于重叠的区间,有四种可能:
1.可行区间 \(cur\) 和后一个温度区间没有重叠
2.两区间左侧或右侧部分重叠
3.可行区间 \(cur\) 包含于后一个温度区间
4.可行区间 \(cur\) 被包含于后一个温度区间
对应AC代码
import java.util.*;
public class Main {
static class Person{
long t, l, h;
Person(long t, long l, long h){
this.t = t;
this.l = l;
this.h = h;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int q = scanner.nextInt();
g:for(int i=0;i<q;i++){
int n = scanner.nextInt(), m = scanner.nextInt();
Person[] p = new Person[n];
for(int j=0;j<n;j++) p[j] = new Person(scanner.nextLong(), scanner.nextLong(), scanner.nextLong());
long left = m - p[0].t, right = m + p[0].t; //以第一个人的到达时间划分初始区间
for(int j=0;j<n;j++){
Person cur = p[j];
if(cur.h < left || cur.l > right){
System.out.println("NO");
continue g;
}else if(j == n - 1){ //如果是最后一个,只要有交集就已经成功
System.out.println("YES");
continue g;
}
if(cur.l >= left && cur.h <= right){ //包含关系
left = cur.l;
right = cur.h;
}else if(cur.l >= left) left = cur.l; //右侧有区间重叠
else if(cur.h <= right) right = cur.h; //左侧有区间重叠
left -= p[j + 1].t - cur.t;
right += p[j + 1].t - cur.t;
}
}
}
}
第一次写题解,可能交代的不是很清楚。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Blog - Floating Ocean!
评论