問題描述
對一個正整數n,如果n在資料檔案中某行的兩個正整數(假設為A和B)之間,即A<=n<=B或A>=n>=B,則n屬於該行;如果n同時屬於行i和j,則i和j有重疊區間;重疊區間的大小是同時屬於行i和j的整數個數。例如,行(10 20)和(12 25)的重疊區間為[12 20],其大小為9;行(20 10)和(12 8)的重疊區間為[10 12],其大小為3;行(20 10)和(20 30)的重疊區間大小為1。
輸入資料:程式讀入已被命名為input.txt的輸入資料文字檔,該檔案的行數在1到1,000,000之間,每行有用一個空格分隔的2個正整數,這2個正整數的大小次序隨機,每個數都在1和2^32-1之間。
輸出資料:在標準輸出上列印出輸入資料檔案中最大重疊區間的大小,如果所有行都沒有重疊區間,則輸出0。
解題思路
定義下界為區間的左端,上界為區間的右端。對每個區間的下界從小到大進行排序,若兩個區間的下界相同,則按上界從小到大進行排序。定義一個max_overlap=0存放當前得到的最大重疊區間,之後順序處理,假設區間存放在一個結構體裡,定義如下:
struct regins{ int left;//區間上界 int right;//區間下界}
如果regins[i].left<regins[i-1].right,說明這兩個區間相交,分為兩種情況:
1、regins[i-1].right>regins[i].right
2、regins[i-1].right<regins[i].right
綜合上述兩種情況,令right_small=min(regins[i].right,regins[i1].right),找出兩個線段上界較小的那個,得到相交區間為right_small-regins[i].left+1,如果該值大於max_overlap,則更新max_overlap。
考慮下面一種情況:
regins[i-1]的上界大於regins[i]的上界,需要將regins[i-1]的上界替換給regins[i],就是的紅色線段部分,然後regins[i]再與regins[i-1]求相交區間,其實也好理解,當regins[i]包含在上一段時,我實際希望比較的是regins[i+1]與regins[i-1],但這個時候,並不關心比regins[i-1].left小的那部分。
令right_big=max(regins[i].right,regins[i-1].right),找出兩個線段中上界較大的那個,把b的值賦給regins[i].right,繼續下一步的處理。
排序的時間複雜度為O(nlogn),比較更新的複雜度為O(n),總的複雜度為O(n)
程式執行個體
<soon>