题意:
给定N个区间,选择任意K个区间,求K个区间中的公共最长区间为多少
思路:
贪心+优先队列
如果选,那么选的区间都是 L尽量小,R尽量大
这样,区间长度最长
当L确定的时候,那么尽量取R最大的
将区间的L从小到大进行排列
然后维护一个R从小到大的优先队列(队列中只有K个元素,多余的弹出)
因为每次拿一个新的区间,L是最大的,即此时L确定,那么尽量的让R最大
即将队列里R最小的取出来
运用了动态数组存储
运用了优先队列(greater是从小到大,less是从大到小)
priority_queue<int, vector<int>, greater<int>> q;
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int n, m;
int ans, L, R;
struct Seg
{
int l, r;
int idx;
bool operator < (const Seg &obj) const
{
return l < obj.l;
}
};
vector<Seg> segs;
priority_queue<int, vector<int>, greater<int>> q;
Seg seg(int _l, int _r, int _idx)
{
Seg ret;
ret.l = _l;
ret.r = _r;
ret.idx = _idx;
return ret;
}
int main()
{
scanf("%d%d", &n, &m);
int _l, _r;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &_l, &_r);
segs.push_back(seg(_l, _r, i + 1));//动态数组存储,i+1表示第几个
}
sort(segs.begin(), segs.end());//按照l大小排序
for(int i = 0; i < n; i++)
{
q.push(segs[i].r);
if(q.size() > m) q.pop();
if(q.size() == m)
{
int candidate = q.top() - segs[i].l + 1;
if(candidate > ans)
{
ans = candidate;
L = segs[i].l;
R = q.top();
}
}
}
printf("%d\n", ans);
if(ans == 0)
{
for(int i = 1; i <= m; i++)
printf("%d ", i);
}
else
{
for(int i = 0; i < n && m > 0; i++)
{
if(segs[i].l <= L && segs[i].r >= R)
{
printf("%d ", segs[i].idx);
m--;
}
}
}
printf("\n");
return 0;
}
代码来源:
https://blog.csdn.net/max_kibble/article/details/54232012