P1803 凌乱的yyy / 线段覆盖——贪心、时间线段覆盖、模拟
题目背景
快 noip 了,yyy 很紧张!
题目描述
现在各大 oj 上有 \(n\) 个比赛,每个比赛的开始、结束的时间点是知道的。
yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。
所以,他想知道他最多能参加几个比赛。
由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参加 \(2\) 个及以上的比赛。
输入格式
第一行是一个整数 \(n\),接下来 \(n\) 行每行是 \(2\) 个整数 \(a_{i},b_{i}\ (a_{i}<b_{i})\),表示比赛开始、结束的时间。
输出格式
一个整数最多参加的比赛数目。
输入输出样例 #1
输入 #1
3
0 2
2 4
1 3
输出 #1
2
说明/提示
- 对于 \(20\%\) 的数据,\(n \le 10\);
- 对于 \(50\%\) 的数据,\(n \le 10^3\);
- 对于 \(70\%\) 的数据,\(n \le 10^{5}\);
- 对于 \(100\%\) 的数据,\(1\le n \le 10^{6}\),\(0 \le a_{i} < b_{i} \le 10^6\)。
题解
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// 定义结构体来存储比赛的开始时间和结束时间
struct Contest {
int start;
int end;
};
// 比较函数,用于按照比赛结束时间对比赛进行排序
bool compare(const Contest& c1, const Contest& c2) {
return c1.end < c2.end;
}
int main() {
int n;
cin >> n;
// 存储所有比赛信息的向量
vector<Contest> contests(n);
// 读取每个比赛的开始时间和结束时间
for (int i = 0; i < n; ++i) {
cin >> contests[i].start >> contests[i].end;
}
// 按照比赛结束时间对比赛进行排序
sort(contests.begin(), contests.end(), compare);
// 初始化参加比赛的数量为 1,因为至少可以参加第一个比赛
int count = 1;
// 记录上一个参加比赛的结束时间
int lastEnd = contests[0].end;
// 遍历排序后的比赛列表
for (int i = 1; i < n; ++i) {
// 如果当前比赛的开始时间大于等于上一个比赛的结束时间
if (contests[i].start >= lastEnd) {
// 可以参加当前比赛,参加比赛的数量加 1
++count;
// 更新上一个参加比赛的结束时间为当前比赛的结束时间
lastEnd = contests[i].end;
}
}
// 输出最多能参加的比赛数量
cout << count << endl;
return 0;
}
浙公网安备 33010602011771号