原題:http://cxsjsx.openjudge.cn/2021finalpractise/A/
描述
小 A 修了 n 門課程, 第 i 門課程是從第 a
i 天一直上到第 b
i 天。
定義兩門課程的沖突程度為 : 有幾天是這兩門課程都要上的。
例如 a
1=1,b
1=3,a
2=2,b
2=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 }