Description
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.
Sample Input
3 2 0 5 -3 2 3 8
2 0 2 3 5
3 2 0 5 -3 3 3 8
1 0 5
利用了sort()排序,提交过程中 一直出现ac不过,显示 超时问题,怎么也找不到解决问题的办法 ,最后 发现原来是 MAX定义的有错误,定义的数组的大小应当至少是 n的两倍,本来觉得这道题特别难,以至于有种想要放弃的感觉 ,还好自己坚持了下来,所以后自己遇到难题不能轻易放弃,坚持 ,再难得的题也一定做得出来
#include <iostream>
#include <algorithm>
#include <cstdio>
#define MAX 2000000
using namespace std;
struct Node
{
int val,op;//val代表存储的点值,op=1代表该点是线段的左端点,0代表该点是线段的右端点
}num[MAX];
bool cmp(Node a,Node b)//从小到大排序,如果a<b,返回真
{
if(a.val!=b.val)
return a.val<b.val;
else
return a.op>b.op;//当读入的两个点是相同的时候。把作为线段头端点的点排在前面
}
int main()
{
int k,n,t=0,cot=0,point[MAX];
scanf("%d%d",&n,&k);
for(int i=0;i<n;i++)//输入线段对应的点的值
{
scanf("%d",&num[t].val);
num[t++].op=1;
scanf("%d",&num[t].val);
num[t++].op=0;
}
sort(num,num+t,cmp);//按从小到大对点的大小排序
int p=0;
for(int i=0;i<t;i++)//某个区间被覆盖至少k次,
//意味着在它前面的区间起点至少有k个且这些区间的终点不能出现在它前面
//这样sort下,直接统计,遇到起点加一,终点减一,每k个一记录就行了
{
if(num[i].op)
{
cot++;
if(cot==k)
point[p++]=num[i].val;
}
else
{
if(cot==k) point[p++]=num[i].val;
cot--;
}
}
cout<<p/2<<endl;//打印区间的个数,p代表点的个数
for(int i=0;i<p;i=i+2)//每次输入两个点,所以i每次加2
cout<<point[i]<<" "<<point[i+1]<<endl;
return 0;
}