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;
}
posted @ 2025-02-17 11:09  ToFuture$  阅读(56)  评论(0)    收藏  举报