解题思路
这是一道区间重叠问题,主要思路如下:
-
问题分析:
- A有 个空闲时间区间
- B有 个空闲时间区间 , 从 到
- 需要找出有多少个 值使得A和B的时间区间有重叠
- 区间重叠意味着存在交集
-
解决方案:
- 枚举每个可能的 值
- 对每个 ,检查A的所有区间和B的所有区间是否存在重叠
- 使用双指针优化区间重叠判断
- 统计满足条件的 值个数
-
实现细节:
- 使用向量存储区间
- 按区间起点排序
- 优化重叠判断逻辑
代码
#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()
算法及复杂度
- 算法:双指针 + 区间遍历
- 时间复杂度: - 为区间数, 为时间范围
- 空间复杂度: - 存储区间信息