相信你是最棒哒!!!
文章目录
题目描述
作为一名计算机科学学生,亚历克斯面临着一个艰难的挑战 --- 洗澡。他尝试每天洗澡,但尽管他尽了最大努力,总是会遇到挑战。他需要 𝑠 分钟来洗澡,而一天只有 𝑚 分钟!
他已经计划了 𝑛 项任务。任务 𝑖 被表示为一个时间区间 (li,𝑟𝑖),这意味着亚历克斯在该时间区间内忙碌,无法洗澡(在 𝑙𝑖 和 𝑟𝑖 之间的任何时刻都不能洗澡)。没有两个任务重叠。
给定所有 𝑛 个时间区间,亚历克斯那天能洗澡吗?换句话说,亚历克斯是否会有一个长度至少为 𝑠 的空闲时间区间?
在第一个测试案例中,亚历克斯可以在一天的前 3 分钟内洗澡,而不会错过任何任务。
输入
第一行包含一个整数 𝑡 (1≤𝑡≤104) --- 测试案例的数量。
每个测试案例的第一行包含三个整数 𝑛 s 𝑚 (1≤𝑛≤2⋅1e5; 1≤𝑠,𝑚≤1e9) --- 亚历克斯已经计划的时间区间数量,亚历克斯洗澡所需的时间,以及一天的分钟数。
接下来有 𝑛 行,第 𝑖 行包含两个整数 𝑙𝑖 和 𝑟𝑖 (0≤𝑙𝑖<𝑟𝑖≤𝑚) --- 第 𝑖 项任务的时间区间。没有两个任务重叠。
输入的附加约束: 𝑙𝑖>𝑟𝑖−1 对于每个 𝑖>1。
所有测试案例的 𝑛 之和不超过 2⋅1e5。
输出
对于每个测试案例,如果亚历克斯可以在该测试案例中洗澡,则输出 "YES"(不带引号),否则输出 "NO"(同样不带引号)。
你可以以任何大小写输出 "YES" 和 "NO"(例如,字符串 "yEs"、"yes" 和 "Yes" 都会被识别为肯定的回答)。
示例
Input | Output |
---|---|
4 3 3 10 3 5 6 8 9 10 3 3 10 1 2 3 5 6 7 3 3 10 1 2 3 5 6 8 3 4 10 1 2 6 7 8 9 |
YES YES NO YES |
正确代码
注释版
#include <iostream>
#include <algorithm> // 包含算法库,这里用于std::max函数
using namespace std; // 使用标准命名空间
int main() {
int t; // 用于存储测试用例的数量
scanf("%d", &t); // 读取测试用例的数量
while (t--) { // 对于每个测试用例
int n, s, m; // 分别存储任务数量、洗澡所需时间和一天的总分钟数
scanf("%d%d%d", &n, &s, &m); // 读取n、s和m的值
int l, r; // 用于存储每个任务的开始和结束时间
int anw = 0, ll = 0; // anw用来存储找到的最大空闲时间,ll用来存储上一个任务的结束时间
while (n--) { // 对于每个任务
scanf("%d%d", &l, &r); // 读取当前任务的开始和结束时间
anw = max(anw, l - ll); // 更新找到的最大空闲时间,即上一个任务结束到当前任务开始的时间
ll = r; // 更新上一个任务的结束时间为当前任务的结束时间
}
anw = max(m - ll, anw); // 更新最大空闲时间为最后一个任务结束到一天结束的时间和之前找到的最大空闲时间中的较大值
if (anw >= s) // 如果最大空闲时间大于等于洗澡所需时间
printf("YES\n"); // 输出YES
else
printf("NO\n"); // 否则输出NO
}
return 0;
}
简洁版
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n, s, m;
scanf("%d%d%d", &n, &s, &m);
int l, r;
int anw = 0, ll = 0;
while (n--) {
scanf("%d%d", &l, &r);
anw = max(anw, l - ll);
ll = r;
}
anw = max(m - ll, anw);
if (anw >= s)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
更详细的代码逻辑
这行代码使用 max
函数比较这两个时间段的长度,并将较大的值赋给 anw
。这样做的目的是确保 anw
始终存储着最大的空闲时间,无论是在任务之间的空闲时间,还是在最后一个任务结束后到一天结束之间的空闲时间。
-
读取测试用例数量:
int t; // 用于存储测试用例的数量 scanf("%d", &t); // 读取测试用例的数量 while (t--) { // 对于每个测试用例
这部分代码首先定义了一个整数变量
t
来存储测试用例的数量,然后使用scanf
函数读取这个值。接着,使用一个while
循环来遍历每个测试用例。 -
读取任务数量、洗澡所需时间和一天的总分钟数:
int n, s, m; // 分别存储任务数量、洗澡所需时间和一天的总分钟数 scanf("%d%d%d", &n, &s, &m); // 读取n、s和m的值
在每个测试用例中,定义了三个整数变量
n
、s
和m
,分别用来存储任务数量、洗澡所需的时间以及一天的总分钟数。然后使用scanf
函数读取这些值。 -
初始化变量:
int l, r; // 用于存储每个任务的开始和结束时间 int anw = 0, ll = 0; // anw用来存储找到的最大空闲时间,ll用来存储上一个任务的结束时间
这里定义了两个变量
l
和r
来存储每个任务的开始和结束时间。另外两个变量anw
和ll
分别用来存储找到的最大空闲时间和上一个任务的结束时间。anw
初始值为0,ll
也初始值为0。 -
遍历每个任务:
while (n--) { // 对于每个任务 scanf("%d%d", &l, &r); // 读取当前任务的开始和结束时间 anw = max(anw, l - ll); // 更新找到的最大空闲时间,即上一个任务结束到当前任务开始的时间 ll = r; // 更新上一个任务的结束时间为当前任务的结束时间 }
这部分代码使用一个
while
循环来遍历每个任务。对于每个任务,使用scanf
函数读取任务的开始时间l
和结束时间r
。然后,使用max
函数更新anw
的值,使其成为当前找到的最大空闲时间。这里的空闲时间是指上一个任务结束到当前任务开始之间的时间。同时,更新ll
的值为当前任务的结束时间。 -
检查最后一个任务后的空闲时间:
anw = max(m - ll, anw); // 更新最大空闲时间为最后一个任务结束到一天结束的时间和之前找到的最大空闲时间中的较大值
在遍历完所有任务后,使用
max
函数更新anw
的值,使其成为最后一个任务结束到一天结束之间的时间与之前找到的最大空闲时间中的较大值。 -
这行代码的作用是更新变量
anw
的值,使其成为两个时间段中的较大者: -
最后一个任务结束到一天结束之间的时间 :
m - ll
m
是一天的总分钟数。ll
是最后一个任务的结束时间。m - ll
计算的是最后一个任务结束后,到一天结束时剩余的时间。
-
之前找到的最大空闲时间 :
anw
- 在遍历任务的过程中,
anw
被不断更新为当前找到的最大空闲时间。
- 在遍历任务的过程中,
-
判断是否有足够的空闲时间洗澡:
if (anw >= s) // 如果最大空闲时间大于等于洗澡所需时间 printf("YES\n"); // 输出YES else printf("NO\n"); // 否则输出NO
最后,判断
anw
(最大空闲时间)是否大于等于s
(洗澡所需的时间)。如果是,则输出"YES",表示亚历克斯有足够的空闲时间洗澡;否则输出"NO",表示亚历克斯没有足够的空闲时间洗澡。