哈理工第八届校团队赛K汪汪汪

题意:

Description

给n个区间[l, r],判断是否存在区间交叉。即是否存在1 <= i < j <= n,使得li < lj < ri < rj。

Input

多组数据每组数据第一行一个整数n,第二行到第n + 1行每行两个数分别代表该区间的左右端点。

Output

如果存在交叉,输出“YES”;否则输出“NO”

Sample Input

2

1 3

2 4

3

1 7

2 4

5 6

Sample Output

YES

NO

Hint

1 <= n <= 1e5, 1 <= li < ri <= 2e5, 每组数据中所有的l,r互不相同。所有组数据n的和不超过1e6.读入数据较大,请使用高效的读入方式。

思路:

​ 利用sort按照l从小到大排序,若l相同则按照r从小到大排序,然后遍历,二分查找即可。

代码:

#include <stdio.h>
#include <algorithm>
using namespace std;

namespace IO {
    const int MX = 4e7;
    char buf[MX];
    int c, sz;

    void begin() {
        c = 0;
        sz = fread(buf, 1, MX, stdin);
    }

    inline bool read(int &t) {
        while (c < sz && buf[c] != '-' && (buf[c] < '0' || buf[c] > '9')) c++;
        if (c >= sz) return false;
        bool flag = 0; if(buf[c] == '-') {
            flag = 1;
            c++;
        }
        for(t = 0; c < sz && '0' <= buf[c] && buf[c] <= '9'; c++)
            t = t * 10 + buf[c] - '0';
        if(flag) t = -t;
        return true;
    }
}

struct node {
    int l, r;
}stu[100005];

int n;

bool zcy(node A, node B) {
    if (A.l == B.l) {
        return A.r < B.r;
    }
    return A.l < B.l;
};

int erfen(int val) {
    int star = 0, endd = n - 1;
    int ans = -1;
    while(star <= endd) {
        int mid = (star + endd) / 2;
        if (stu[mid].l <= val) {
            star = mid + 1;
        } else {
            ans = mid;
            endd = mid - 1;
        }
    }
    return ans;
}

int main () {
    IO::begin();
    while (IO::read(n)) {
        for (int i = 0; i < n; i++) {
            IO::read(stu[i].l);
            IO::read(stu[i].r);
        }
        sort(stu, stu + n, zcy);
        int flag = 0;
        for (int i = 0; i < n - 1; i++) {
            int inx = erfen(stu[i].l);
            if (inx == -1) {
                break;
            }
            for (int j = inx; j < n && stu[j].l < stu[i].r; j++) {
                if(stu[j].r > stu[i].r) {
                    flag = 1;
                    break;
                }
            }
            if (flag) {
                break;
            }
        }
        if (flag) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }
    return 0;
}

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/84945527