牛客周赛116-D-小红的区间相交
本文最后更新于 22 天前,其中的信息可能已经有所发展或是发生改变|´・ω・)ノ

原题链接:D-小红的区间相交_牛客周赛 Round 116

由题目内容可知,我们要判断n个区间是否均是两两相交。

很明显,我们会想到一种情况(其实是必须是这个样子),假设我们有四个区间

如下图所示:

我们不难想到,如果我们对输入的n个区间进行排序,按照L升序排列的结果(这个结果指的是排序后的区间顺序)应该与按照R升序排列的结果一样。也就是maxL <= minR

但是,有一种情况要特判,如下图:

这种情况也满足maxL <= minR,但是maxLminR来自同一个区间,我们在这里做特判就行。

以下是题解代码:

#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define x first
#define y second
#define pb push_back
#define pf push_front
#define ssize(x) (int)(x.size())
#define LF "\n"

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N = 1e5 + 10;
const int dx[4] = { 0, 1, 0, -1 };
const int dy[4] = { 1, 0, -1, 0 };

typedef struct {
    int l;
    int r;
    int id;
}qj;

bool isSame(qj a, qj b) {
    return a.id == b.id;
}

bool cmpByL(qj a, qj b) {
    if(a.l == b.l) return a.r < b.r;
    return a.l < b.l;
}

bool cmpByR(qj a, qj b) {
    if(a.r == b.r) return a.l < b.l;
    return a.r < b.r;
}

void slove() {
    int n;
    cin >> n;
    vector<qj> qjsA, qjsB;
    for (int i = 0; i < n; i++) {
        int l, r;
        cin >> l >> r;
        qjsA.pb({ l, r, i + 1 });
        qjsB.pb({ l, r, i + 1 });
    }
    sort(qjsA.begin(), qjsA.end(), cmpByL);
    sort(qjsB.begin(), qjsB.end(), cmpByR);

    bool ABIsSame = true;

    for (int i = 0; i < n; i++) {
        if (!isSame(qjsA[i], qjsB[i])) {
            ABIsSame = false;
            break;
        }
    }

    int MaxL = qjsA[n - 1].l;
    int MinR = qjsB[0].r;

    if (isSame(qjsA[n - 1], qjsB[0])) {
        cout << "No" << LF;
        return;
    }
    else if (MaxL <= MinR && ABIsSame) {
        cout << "Yes" << LF;
        return;
    }
    else {
        cout << "No" << LF;
        return;
    }
}

int main() {
    IOS;
    int T = 1;
    cin >> T;
    while (T--) {
        slove();
    }
    return 0;
}

说说代码思路,代码中我们创建了两个vector容器(你可以理解为动态数组),存储的内容均为n个区间,并且内容完全相同。

然后我们分别对这两个容器进行升序排序,A容器以区间的L大小进行排序,如果L相同则以R进行排序(很重要)。B容器同理,优先以R升序,R相同则以L升序。然后找出maxL和minR(最大的起点和最小的终点)。

然后就是检查排完序后的两个容器中的区间顺序是否相同,这里用一个布尔类型的变量保存结果。

这时就要进入判断部分了,我们先要判断maxLminR是否来自同一个区间,也就是上文说的要特判的地方,然后就是判断条件maxL <= minRABIsSame是否满足。

看到这里,我必须要解释一种情况,也就是输入的所有区间都相同的情况,这个代码为什么也会输出”Yes”。

我们来看结构体qj的代码

typedef struct {
    int l;
    int r;
    int id; //这个地方很重要
}qj;

有一个成员属性是id,用来标记此区间是第几个输入的,同时也是判断两个区间是否相同的重要变量。

bool isSame(qj a, qj b) {
    return a.id == b.id;
}

我们现在来模拟一遍:

有一组完全相同的区间数据输入了程序。在输入时,程序为每个输入的区间进行了id标记。

然后就是排序,因为 sort 函数这里是稳定的,而且完全不用排序。所以这里排完序后的A、B容器里的(qj)区间元素顺序是完全相同的。

然后就来到了判断的地方:

if (isSame(qjsA[n - 1], qjsB[0])) {
        cout << "No" << LF;
        return;
    }
    else if (MaxL <= MinR && ABIsSame) {
        cout << "Yes" << LF;
        return;
    }
    else {
        cout << "No" << LF;
        return;
    }

注意这里的isSame(qjsA[n - 1], qjsB[0])这里会返回false

因为qjsA[n - 1], qjsB[0]这两个区间(qj)的id属性不相同

最后,我来说说排序的问题,就拿A容器的排序来说吧。如果我们在L相同的情况下没有特殊处理。就像下面这样:

bool cmpByL(qj a, qj b) {
    return a.l < b.l;
}

这样就相当于没有排序

我们用一个样例:

1
3
1 2
1 4
1 3

如果我们排序的时候在L或者R相同的情况下没有特殊处理,就会导致排完序后的A、B中的区间顺序不相同。这里就会输出”No”。

评论

  1. 哈哈
    3 周前
    2025-11-05 15:16:17

    你这个题解有问题,只是牛客测试数据太弱给你过了,你试试
    1
    3
    1 4
    2 10
    3 5,你的输出是Yes,实际上区间3在区间2里面

    • 博主
      哈哈
      3 周前
      2025-11-05 19:37:03

      已修改,感谢指正

  2. 哈哈
    3 周前
    2025-11-05 15:28:20

    还要加一个qjsA和qjsA每一位的id按顺序一一对应

    • 博主
      哈哈
      3 周前
      2025-11-05 18:55:44

      其实光加这个还不行,过不了
      1
      3
      1 2
      1 4
      1 3
      这情况,当时还是想得太草率了。

  3. 白鱼
    3 周前
    2025-11-05 19:46:19

    阿巴阿巴

    • 博主
      白鱼
      3 周前
      2025-11-05 19:49:54

      阿巴阿巴

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇