题目:http://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1892
这题快搞疯我了,一开始以为直接排序然后取相邻,后来发现不行。
在询问了大佬之后大佬给讲了一下,茅塞顿开,顿时觉得我可能长了个假脑。
在找两组的时候,即k = 2时,排序区间左端点,维护最大区间右端点,有以下递推式:
第i个区间[a,b]:
ans = max(ans, min(maxr, b) - a + 1);
maxr = max(maxr, b);
同样的,当k可以去任意数时,我们只需要将维护最大区间右端点改成维护第k - 1大区间右端点即可
维护方法:用小根堆维护k - 1个数,如果新的区间右端点比小根堆堆顶元素要大,那就交换一下再维护一下小根堆
然后vs上的max和min貌似用不了,就手写了一个
有思路以后又wa了一次,原因是我在最后输出ans + 1,没有考虑到答案为0(区间都不重复)的情况
改了以后又RE了,原因是没有考虑到k == 1的情况即small.top()不存在,于是加上了判断k == 1
然后就喜闻乐见的超时了。。。手打的快排竟然撑不过300000。。。我也是ri le gou le。。。
学了一下sort的结构体用法以后,终于ac了。。。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm> //sort
#include <queue> //根堆
#include <functional> //小根堆里的greater<int>
using namespace std;
struct RULER {
int x;
int y;
}ruler[400000] = { 0 };
int max(int a, int b) //vs上的max和min貌似用不了
{
return a > b ? a : b;
}
int min(int a, int b)
{
return a < b ? a : b;
}
bool comparison(struct RULER l, struct RULER r) //结构体排序的参数
{
return l.x < r.x;
}
/*void Sort(int l, int r) //一开始手打排序,结果莫名其妙才300000就超时了...
{
if (l >= r)
return;
int pivot = ruler[l].x;
int pivotors = l;
for (int i = l + 1; i <= r; i++)
{
if (ruler[i].x < pivot) {
pivotors++;
swap(ruler[pivotors], ruler[i]);
}
}
swap(ruler[l], ruler[pivotors]);
Sort(l, pivotors - 1);
Sort(pivotors + 1, r);
}*/
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++)
scanf("%d%d", &ruler[i].x, &ruler[i].y);
sort(ruler, ruler + n, comparison);
priority_queue<int, vector<int>, greater<int> > small;
for (int i = 0; i < k - 1; i++)
small.push(ruler[i].y);
int ans = 0, maxr;
//maxr = small.top(); 没有考虑k == 1的情况
if (k == 1)
maxr = 2000000000;
else
maxr = small.top();
for (int i = k - 1; i < n; i++) {
ans = max(ans, min(maxr, ruler[i].y) - ruler[i].x + 1);
if (ruler[i].y > maxr) {
small.pop();
small.push(ruler[i].y);
maxr = small.top();
}
}
cout << ans << endl;
return 0;
}
顺便给自己做个关于根堆和快排的笔记:
priority_queue<int> //xxx 大根堆 #include <queue>
priority_queue<int, vector<int>, greater<int>> //xxxx 小根堆 #include <queue> #include <functional>
xxx.top() //访问最值
xxx.push() //插入最值(插入后自动维护)
xxx.pop() //删除最值(删除后自动维护)
#include <algorithm>
bool comparison(struct RULER l, struct RULER r)
{
return l.x < r.x; //从小到大
}
sort(ruler, ruler + n, comparison);
顺便贴一下一个相似题的一解题报告:http://blog.csdn.net/chj_zmr/article/details/8800313
最后感谢一下那个教我题大佬顺便膜一发orz