題目大意:
給你n個區間,求k個區間的最大並區間長度。
題目解法:
貪心,不斷想優先隊列中保存內容,保證每次隊列頂端的右值最大,不斷修正左區間。最後按照最優的左端點和右端點,尋找答案就行。
代碼:
#include "iostream"
#include "cstdio"
#include "math.h"
#include "algorithm"
#include "string"
#include "string.h"
#include "vector"
#include "map"
#include "queue"
using namespace std;
int n, k;
struct Node {
int left, right, id;
friend bool operator <(Node a, Node b) {
return a.right > b.right;
}
}node[300010];
bool cmp(Node a, Node b) {
if (a.left == b.left)
return a.right > b.right;
return a.left < b.left;
}
int main() {
scanf("%d %d", &n, &k);
for (int i = 1;i <= n;i++) {
scanf("%d %d", &node[i].left, &node[i].right);
node[i].id = i;
}
int maxnum = 0, ansleft, ansright;
sort(node + 1, node + n + 1, cmp);
priority_queue<Node>que;
for (int i = 1;i <= n;i++) {
int left = node[i].left;
que.push(node[i]);
if (que.size() > k)
que.pop();
int right = que.top().right;
if (que.size() == k&&right - left + 1 > maxnum) {
maxnum = right - left + 1;
ansleft = left;
ansright = right;
}
}
printf("%d\n", maxnum);
if (maxnum == 0) {
for (int i = 1;i <= k;i++) {
printf("%d ", i);
}
}
else {
for (int i = 1, j = 0;i <= n&&j < k;i++) {
if (node[i].left <= ansleft&&node[i].right >= ansright) {
printf("%d ", node[i].id);
j++;
}
}
}
return 0;
}