解题思路

这是一道区间重叠问题,主要思路如下:

  1. 问题分析:

    • A有 个空闲时间区间
    • B有 个空闲时间区间
    • 需要找出有多少个 值使得A和B的时间区间有重叠
    • 区间重叠意味着存在交集
  2. 解决方案:

    • 枚举每个可能的
    • 对每个 ,检查A的所有区间和B的所有区间是否存在重叠
    • 使用双指针优化区间重叠判断
    • 统计满足条件的 值个数
  3. 实现细节:

    • 使用向量存储区间
    • 按区间起点排序
    • 优化重叠判断逻辑

代码

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

int main() {
    int p, q, l, r;
    while (cin >> p >> q >> l >> r) {
        // 存储A的空闲时间区间
        vector<int> v1(2 * p);
        for (int i = 0; i < p; ++i) {
            cin >> v1[2*i] >> v1[2*i + 1];
        }
        
        // 存储B的空闲时间区间
        vector<int> v2(2 * q);
        for (int i = 0; i < q; ++i) {
            cin >> v2[2*i] >> v2[2*i + 1];
            v2[2*i] += l;      // 初始化为最小时间l
            v2[2*i + 1] += l;
        }
        
        int res = 0;
        // 枚举每个可能的时间t
        for (int k = 0; k <= r - l; ++k) {
            if (k != 0) {
                // 移动B的时间区间
                for (int i = 0; i < 2*q; ++i) {
                    v2[i] += 1;
                }
            }
            
            // 检查是否存在重叠
            int bg = 0, pos = 0;
            while (bg < v1.size() && pos < v2.size()) {
                int left = v1[bg], right = v1[bg + 1];
                
                if (v2[pos] < left) {
                    pos += 1;
                } else if (v2[pos] >= left && v2[pos] <= right) {
                    res += 1;
                    break;
                } else {
                    bg += 2;
                }
            }
        }
        cout << res << endl;
    }
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            int p = sc.nextInt();
            int q = sc.nextInt();
            int l = sc.nextInt();
            int r = sc.nextInt();
            
            // 存储A的空闲时间区间
            int[] v1 = new int[2 * p];
            for (int i = 0; i < p; i++) {
                v1[2*i] = sc.nextInt();
                v1[2*i + 1] = sc.nextInt();
            }
            
            // 存储B的空闲时间区间
            int[] v2 = new int[2 * q];
            for (int i = 0; i < q; i++) {
                v2[2*i] = sc.nextInt() + l;
                v2[2*i + 1] = sc.nextInt() + l;
            }
            
            int res = 0;
            // 枚举每个可能的时间t
            for (int k = 0; k <= r - l; k++) {
                if (k != 0) {
                    // 移动B的时间区间
                    for (int i = 0; i < 2*q; i++) {
                        v2[i]++;
                    }
                }
                
                // 检查是否存在重叠
                int bg = 0, pos = 0;
                while (bg < v1.length && pos < v2.length) {
                    int left = v1[bg];
                    int right = v1[bg + 1];
                    
                    if (v2[pos] < left) {
                        pos++;
                    } else if (v2[pos] >= left && v2[pos] <= right) {
                        res++;
                        break;
                    } else {
                        bg += 2;
                    }
                }
            }
            System.out.println(res);
        }
        sc.close();
    }
}
def solve():
    p, q, l, r = map(int, input().split())
    
    # 存储A的空闲时间区间
    v1 = []
    for _ in range(p):
        a, b = map(int, input().split())
        v1.extend([a, b])
    
    # 存储B的空闲时间区间
    v2 = []
    for _ in range(q):
        c, d = map(int, input().split())
        v2.extend([c + l, d + l])
    
    res = 0
    # 枚举每个可能的时间t
    for k in range(r - l + 1):
        if k != 0:
            # 移动B的时间区间
            v2 = [x + 1 for x in v2]
        
        # 检查是否存在重叠
        bg = pos = 0
        while bg < len(v1) and pos < len(v2):
            left, right = v1[bg], v1[bg + 1]
            
            if v2[pos] < left:
                pos += 1
            elif left <= v2[pos] <= right:
                res += 1
                break
            else:
                bg += 2
    
    return res

def main():
    while True:
        try:
            print(solve())
        except EOFError:
            break

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:双指针 + 区间遍历
  • 时间复杂度: - 为区间数, 为时间范围
  • 空间复杂度: - 存储区间信息