整數區間


【題目描述】

一個整數區間[A,B]
請編程完成以下任務:
1.從文件中讀取區間的個數及其它們的描述;
2.找到滿足下述條件的所含元素個數最少的集合中元素的個數,對於每一個區間,都至少有兩個不同的整數屬於該集合。


【輸入】
首行包括區間的數目n,1<=n<=10000,接下來的n 行,每行包括兩個整數a,b,被一空格隔開,0<=a<=b<=10000,它們是某一個區間的開始值和結束值。


【輸出】
第一行集合元素的個數,對於每一個區間都至少有兩個不同的整數屬於該區間,且集合所包含元素數目最少。


樣例輸入
43
6
2 4
0 2
4 7


樣例輸出
4

 

 

這道題的題目說的很迷,說人話就是求一個集合,使每一個區間在這個集合里面都至少有兩個元素,輸出集合元素。

 

一種 O(n ^ 2) 的算法是先開一個標記數組,記錄集合的元素取了哪些。然后按區間開始的端點從小到大排序,從后往前找。開始先標記最后一個區間的前兩個值,然后每一次循環都遍歷該區間的所有數,看看有幾個被放到了集合里。若有兩個,就進行下一次循環;若一個,就標記區間第一個值,ans++;若沒有,就標記區間前兩個值,ans += 2。

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 using namespace std;
 7 
 8 #define rep(i ,a, n) for(int i = a; i <= n; ++i)
 9 #define per(i, n, a) for(int i = n; i >= a; --i)
10 typedef long long ll;
11 const int maxn = 1e4 + 5;
12 
13 struct Node
14 {
15     int sta, end;
16     bool operator < (const Node& other)const
17     {
18         return sta < other.sta;
19     }
20 }a[maxn];
21 int n;
22 int vis[maxn], sum = 0;
23 int main()
24 {
25     freopen("a.in", "r", stdin);
26     freopen("a.out", "w", stdout);
27     scanf("%d", &n);
28     rep(i, 1, n) scanf("%d%d", &a[i].sta, &a[i].end);
29     sort(a + 1, a + n + 1);
30     per(i, n, 1)
31     {
32         int tot = 0;
33         rep(j, a[i].sta, a[i].end) if(vis[j]) tot++;
34         if(tot == 0) {sum += 2; vis[a[i].sta] = vis[a[i].sta + 1] = 1;}
35         else if(tot == 1) {sum++; vis[a[i].sta] = 1;}
36     }
37     printf("%d\n", sum);
38     return 0;
39 }

這個算法為什么成立呢?因為我們每一次取的都是區間的前兩個值,這樣做就是使所取得這兩個值在接下來的區間中的概率最大,從而在后面的查詢中盡量少的添加集合中的元素。

 


我們發現,對於每一次區間的操作,只是都用了區間中的前兩個元素。這樣就可以開兩個變量記錄,就不用開數組遍歷了。(默認flag1 < flag2)

若區間末尾大於flag2 ,那么就說明這個區間至少有兩個數被選進集合中了,過;若在flag1 和 flag2 之間,吧 flag1 變成 flag2,flag1 變成 區間開始值;若小於 flag1 ,flag1 和 flag2 分別變成區間頭和頭+1.

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 #define rep(i, a, n) for(int i = a; i <= n; ++i)
 8 #define per(i, n, a) for(int i = n; i >= a; --i)
 9 typedef long long ll;
10 const int maxn = 1e4 + 5;
11 
12 struct Node
13 {
14     int sta, end;
15     bool operator < (const Node& other)const
16     {
17         return sta < other.sta;
18     }
19 }a[maxn];
20 int n, flag1, flag2;
21 int ans = 0;
22 int main()
23 {
24     freopen("a.in", "r", stdin);
25     freopen("a.out", "w", stdout);
26     scanf("%d", &n);
27     rep(i, 1, n) scanf("%d%d", &a[i].sta, &a[i].end);
28     sort(a + 1, a + n + 1);
29     flag1 = a[n].sta; flag2 = flag1 + 1; ans += 2;
30     per(i, n - 1, 1)
31     {
32         if(a[i].end < flag1)
33         {
34             flag1 = a[i].sta; flag2 = flag1 + 1;
35             ans += 2;
36         }
37         else if(a[i].end >= flag1 && a[i].end < flag2)
38         {
39             flag2 = flag1; flag1 = a[i].sta;
40             ans++;
41         }
42     }
43     printf("%d\n", ans);
44     return 0;
45 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM