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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章