程设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 }