程设2021期末题A:上课时间

原题:http://cxsjsx.openjudge.cn/2021finalpractise/A/

描述

小 A 修了 n 门课程, 第 i 门课程是从第 ai 天一直上到第 bi 天。
定义两门课程的冲突程度为 : 有几天是这两门课程都要上的。
例如 a1=1,b1=3,a2=2,b2=4 时, 这两门课的冲突程度为 2。
现在你需要求的是这 n 门课中冲突程度最大的两门课的冲突程度。

输入

第一行一个正整数 n 表示课程数量。
接下来 n 行,每行两个正整数 ai,bi
2 ≤ n≤ 1000, 1 ≤ ai ≤ bi ≤ 1000。

输出

输出一个整数表示最大的冲突程度

样例输入

3
1 3
2 4
5 5

样例输出

2 

解法

思路:枚举+剪枝

复杂度为O(n^2)

为了剪枝,先排序,开始时间早的排在前面,如果开始时间相同就把结束时间早的排在前面。然后两重循环考察课程的重叠程度。

坑:可能会有(1,4),(2,3)这种课程,所以不能直接用排在后面的课程来剪排在前面的课程。排在前面的课程也可能后结束。

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 struct project {
 6     int start;
 7     int end;
 8     project(int a,int b):start(a),end(b){}
 9     bool operator <(const project A)const {
10         if (start == A.start)
11             return end < A.end;
12         else
13             return start < A.start;
14     }
15 };
16 int main() {
17     int n;
18     cin >> n;
19     vector<project>alls;
20     for (int i = 0; i < n; i++)
21     {
22         int a, b;
23         cin >> a >> b;
24         alls.push_back(project(a, b));
25     }
26     sort(alls.begin(), alls.end());
27     int result = 0;
28     for (int i = 0; i < n; i++) {
29         if (alls[i].end - alls[i].start < result)//剪枝
30             continue;
31         for (int j = i + 1; j < n; j++) {
32             if (alls[j].start > alls[i].end)
33                 break;
34             int t = min(alls[i].end, alls[j].end) - alls[j].start + 1;
35             result = max(t, result);
36         }
37     }
38     cout << result << endl;
39     return 0;
40 }

 

posted @ 2021-07-19 20:49  永远是个小孩子  阅读(1106)  评论(0编辑  收藏  举报