Openjudge NOI題庫2.4基本演算法之分治 7620:區間合併
阿新 • • 發佈:2019-02-20
總時間限制: 1000ms 記憶體限制: 65536kB
- 描述
-
給定 n 個閉區間 [ai; bi],其中i=1,2,...,n。任意兩個相鄰或相交的閉區間可以合併為一個閉區間。例如,[1;2] 和 [2;3] 可以合併為 [1;3],[1;3] 和 [2;4] 可以合併為 [1;4],但是[1;2] 和 [3;4] 不可以合併。
我們的任務是判斷這些區間是否可以最終合併為一個閉區間,如果可以,將這個閉區間輸出,否則輸出no。
- 輸入
- 第一行為一個整數n,3 ≤ n ≤ 50000。表示輸入區間的數量。
之後n行,在第i行上(1 ≤ i ≤ n),為兩個整數 ai 和 bi ,整數之間用一個空格分隔,表示區間 [ai; bi](其中 1 ≤ ai ≤ bi ≤ 10000)。 - 輸出
- 輸出一行,如果這些區間最終可以合併為一個閉區間,輸出這個閉區間的左右邊界,用單個空格隔開;否則輸出 no。
- 樣例輸入
-
5 5 6 1 5 10 10 6 9 8 10
- 樣例輸出
-
1 10
-
思路:資料的儲存肯定選擇結構體陣列了,因為方便遍歷嗎,然後儲存的時候,它輸入不一定前面大後面小,所以在輸入的時候我就先把區間左右大小分好存進結構體,前面輸入資料部分程式碼能看懂 就不多說了,z是左,y是右,qq是我定義的qj(區間)型別的陣列,然後比較部分,就像我們看這個區間是否能合併一樣,先按區間(按照左界,左界相等看右界)排序,像(1,3)(2,4)這種情況是最好做的,只需要看相鄰左右界限,但是對於(1,8)(2,7),要是隻看相鄰左右就不行了,8比2大是沒錯,可能得出來的結果是(1,7),這種情況對於如果一開始記錄左界最大和右界最小值還是好計算的,但是對於(1,9)(2,4),(6,8)就會判斷錯誤,所以在比較過程中我們要找右界最大的,讓它跟左界一直比較,左界可以比他小,但是不能比他大,一旦比他大就直接輸出no並且返回0。這就是為啥一定要有
-
qq[1].y=max(qq[1].y,qq[i].y);
-
思路清晰了程式碼就好看了,沒加太多註釋
-
#include <stdio.h> #include<iostream> #include<algorithm> using namespace std; struct qj{//區間 結構體 int z,y;//左 右 }; qj qq[50000]; int zz=50000,yy=-50000; int cmp(qj &a,qj &b) { if(a.z<b.z)return 1;//左界小返回1 if(a.z>b.z)return 0;//左界大返回0 else { if(a.y<b.y)return 1;//左界相同返回右界小的 else return 0; } } int main() { int n,x1,x2,t; cin>>n; for(int i=1;i<=n;i++) { cin>>x1>>x2; if(x1<x2) { t=x1;x1=x2;x2=t; } qq[i].y=x1; qq[i].z=x2;//使得左界永遠小於等於左界 if(qq[i].z<=zz)zz=qq[i].z; if(qq[i].y>=yy)yy=qq[i].y; } sort(qq+1,qq+n+1,cmp);//對區間排序 for(int i=2;i<=n;i++) { if(qq[1].y<qq[i].z) //如果左界大於右界 返回 { cout<<"no"; return 0; } else qq[1].y=max(qq[1].y,qq[i].y); } cout<<zz<<" "<<yy;//輸出該輸入的區間中左界最小和右界最大 return 0; }