D. The Union of k-Segments(貪心)

題目鏈接:D. The Union of k-Segments

D. The Union of k-Segments
time limit per test4 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given n segments on the coordinate axis Ox and the number k. The point is satisfied if it belongs to at least k segments. Find the smallest (by the number of segments) set of segments on the coordinate axis Ox which contains all satisfied points and no others.

Input
The first line contains two integers n and k (1 ≤ k ≤ n ≤ 106) — the number of segments and the value of k.

The next n lines contain two integers li, ri ( - 109 ≤ li ≤ ri ≤ 109) each — the endpoints of the i-th segment. The segments can degenerate and intersect each other. The segments are given in arbitrary order.

Output
First line contains integer m — the smallest number of segments.

Next m lines contain two integers aj, bj (aj ≤ bj) — the ends of j-th segment in the answer. The segments should be listed in the order from left to right.

Examples
inputCopy
3 2
0 5
-3 2
3 8
outputCopy
2
0 2
3 5
inputCopy
3 2
0 5
-3 3
3 8
outputCopy
1
0 5

題目大意:給你n個線段,問:最少重疊k次的部分有多少個(最少個數),每一部分的範圍是多少。

思路:
貪心的思想,查找重疊部分超過m次的開始和結尾。

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<math.h>
#include<bits/stdc++.h>
#include<string>
#include<algorithm>
using namespace std;
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;

const int maxn=1e6+9;

struct node
{
    int s,p;
} edge[maxn*2];
int cun[maxn*2];
bool cmp(node a,node b)
{
    if(a.s==b.s) return a.p>b.p;//一定是開始端點在前
    return a.s<b.s;
}



int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        int len=0;
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&edge[len].s,&edge[len+1].s);
            edge[len++].p=1;//開始端
            edge[len++].p=0;//結束端
        }
        sort(edge,edge+len,cmp);

        int ans=0;
        int sum=0;
        for(int i=0;i<len;i++)
        {
            if(edge[i].p)//遇到開始端
            {
                sum++;//要先加加
                if(sum==m)//剛好遇到重疊m次的開始端
                    cun[ans++]=edge[i].s;
            }
            else//結束端
            {
                if(sum==m)//剛好遇到重疊m次的結束端
                    cun[ans++]=edge[i].s;
                sum--;//判斷完,再減減
            }
        }
        printf("%d\n",ans/2);
        for(int i=0;i<ans;i+=2)
            printf("%d %d\n",cun[i],cun[i+1]);
    }
    return 0;
}
發佈了186 篇原創文章 · 獲贊 14 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章