依次增加起床时间,将B的空闲时间不断后移,每次增加后判断是否与A的空闲时间相交

#include <iostream>
#include <vector>
using namespace std;

// 判断两个时间段是否相交
bool isIntersect(pair<int, int> a, pair<int, int> b) {
    if (a.first <= b.first && a.second <= b.second && a.second >= b.first) {
        return true;
    }
    if (b.first <= a.first && b.second <= a.second && b.second >= a.first) {
        return true;
    }
    return false;
}

int main() {
    int p, q, l, r;
    while (cin >> p >> q >> l >> r) {
        vector<pair<int, int>> atime(p);
        vector<pair<int, int>> btime(q);
        for (int i = 0; i < p; i++) {
            cin >> atime[i].first >> atime[i].second;
        }
        for (int i = 0; i < q; i++) {
            cin >> btime[i].first >> btime[i].second;
        }
        int ans = 0; // 返回答案
        bool flag = false; // 标志是否找到相交
        for (int i = l; i <= r; i++) {
            auto tmp = btime; // 每次最外层循环复制一份,避免原数据被改写
            // 把B的所有空闲时间都增加相应的起床时刻值
            for (int j = 0; j < q; j++) {
                tmp[j].first += i;
                tmp[j].second += i;
            }
            // 两两遍历a和b的所有空闲时间,判断是否相交
            for (int m = 0; m < p; m++) {
                flag = false;
                for (int n = 0; n < q; n++) {
                    if (isIntersect(atime[m], tmp[n])) {
                        ans++;
                        flag = true;
                        break;
                    }
                }
                // 找到一组相交的就提前跳出
                if (flag) {
                    break;
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

时间复杂度:最耗时的操作是双重循环,其中外层循环遍历了时间段 [l, r] 中的每一个时间点,内层循环遍历了两个人的所有空闲时间段,因此时间复杂度为 O((r-l+1) * p * q),其中 p 和 q 分别表示两个人的空闲时间段数

空间复杂度:使用了两个 vector,分别存储了两个人的空闲时间段,因此空间复杂度为 O(p+q)