http://acm.csu.edu.cn:20080/csuoj/problemset/problem?pid=2202
Description
凤凰院凶真又双叒叕踏上了拯救牧濑红莉栖之路,现在有 NN 条世界线 [l1,r1],[l2,r2],...,[lN,rN][l1,r1],[l2,r2],...,[lN,rN] 。
从这些世界线中选出 KK 个,考虑其交集,即被所 有 KK 个世界线包含的点集。交集必然也是一个世界线,设为 [l,r][l,r] ,则其长度为 r−lr−l 。
只有世界线的交集最大,冈部才有足够的时间完成任务。 请求出所有选出 KK 个世界线的方案中,交集长度最大的。
Input
输入的第一行包含一个整数 TT ,代表测试数据的组数。接下来是 TT 组数据。
每组数据的第一行包含两个整数 NN 和 KK 。接下来NN 行,每行包含两个整数 lili 和 riri ,描述一 个世界线。
Output
对于每组数据,输出一行,包含一个整数,代表交集的最大长度。
Sample Input
1 3 2 1 6 2 4 3 6
Sample Output
3
Hint
1≤T≤10001≤T≤1000
1≤K≤N≤1051≤K≤N≤105
1≤li≤ri≤1091≤li≤ri≤109
∑n≤5∗105∑n≤5∗105
Source
Author
xm
思路:贪心,读入数据按照区间左端点排序,然后遍历序列,用优先队列维护区间右端点的最小值,当队列中有k个元素的时候,更新最大值MAX=max(q.top()-a[i].l),(此时交集的左端点的最大值一定是a[i].l)当队列中元素>k个时,进行出队操作。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int l,r;
bool operator <(const node& a)
{
return l<a.l;
}
};
int t;
int n,k;
node a[100005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&k);
for(int i=0;i<n;i++)
scanf("%d %d",&a[i].l,&a[i].r);
sort(a,a+n);
priority_queue<int,vector<int>,greater<int> > q;
int MAX=0;
for(int i=0;i<n;i++)
{
q.push(a[i].r);
if(q.size()>k)
q.pop();
if(q.size()==k)
MAX=max(MAX,q.top()-a[i].l);
}
printf("%d\n",MAX);
}
return 0;
}