[題解] [暴力] CodeForces 976/C C. Nested Segments
訓練賽http://codeforces.com/group/NVaJtLaLjS/contest/236426/problem/B
即http://codeforces.com/problemset/problem/976/C
題意:輸入n個區間 (1 ≤ n ≤ 3·105),輸出任意兩個嵌套區間的編號。不存在輸出-1 -1。
輸出沒有唯一答案,而且子區間在前。滿足A ≤ a < b ≤ B 則 (a,b) 是 (A,B) 子區間。
參考下圖,第2行的區間是3、4、5、6行的子區間,而不是11
示例:
Input:
5 1 10 2 9 3 9 2 3 2 9
Output:
2 1
該示例有多個答案,比如
3 1或4 1;
3 2或4 2;
2 5或5 2。
Input:
3 1 5 2 6 6 20
Output:
-1 -1
這題不是無腦暴力,這數據量太大了,逐一比較會導致超時。所以要找出其中規律。
嵌套區間的判斷條件已經知道了:A
≤ a < b ≤ B,那麽非嵌套的呢?
看圖,a < A且b < B,則 (a,b) (A,B) 區間不嵌套。
你想到了什麽?
把示例2的圖畫出來,你會發現每個區間的左右端點都比前一個大。
只有這種情況下不存在嵌套區間。我想到這裏你已經知道要怎麽做了。
把輸入的區間進行排序,按左端點或者右端點從小到大排序。
假設不存在嵌套區間,那麽從1到N遍歷,代表區間左右端點的變量F,B必定嚴格遞增。
如果不是,說明有區間是嵌套的,停下判斷兩個區間的大小,按順序輸出兩個編號即可結束;
否則在遍歷完成後輸出-1 -1表明沒有嵌套區間的存在。
需要一個結構體來存區間端點及其編號,再對結構體排序,以保證排序不會打亂這些信息。
對結構體排序,當然要把大小判斷告訴sort/qsort函數。
醜代碼如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 struct Segment 6 { 7 int left,right; 8 int num; 9 }sgmt[300003]={{0}}; 10 int N=0; 11 12 int compare(const void *p1,const void *p2) 13 { 14 struct Segment *a=p1,*b=p2; 15 return a->left - b->left ; 16 } 17 18 int Answer(int A,int B) 19 { 20 int lenA=sgmt[A].right-sgmt[A].left; 21 int lenB=sgmt[B].right-sgmt[B].left; 22 if(lenA<lenB) 23 { 24 printf("%d %d\n",sgmt[A].num,sgmt[B].num); 25 } 26 else 27 { 28 printf("%d %d\n",sgmt[B].num,sgmt[A].num); 29 } 30 } 31 32 int main() 33 { 34 scanf("%d",&N); 35 for(int n=0;n<N;n++) 36 { 37 scanf("%d%d",&sgmt[n].left,&sgmt[n].right); 38 sgmt[n].num=n+1; 39 } 40 qsort(sgmt,N,sizeof(struct Segment),compare); 41 42 int front=sgmt[0].left,back=sgmt[0].right; 43 for(int n=1;n<N;n++) 44 { 45 if( sgmt[n].left > front && sgmt[n].right > back ) 46 { 47 front=sgmt[n].left,back=sgmt[n].right; 48 } 49 else 50 { 51 Answer(n-1,n); 52 return 0; 53 } 54 } 55 puts("-1 -1"); 56 return 0; 57 }
[題解] [暴力] CodeForces 976/C C. Nested Segments