题目大意:给你那个区间,问哪些区间断的重叠区间的个数大于等于k,输出最小区间数(要合并)
思路:将左右端点分开(不在一个结构体里)保存在一个数组,加标记确定左端点还是右端点,排序,遇到左端点ans++,右端点ans--,大于等于k则记录…………
最后区间合并时出现了问题,想了好久,慌了……最后有一点,排序时必须按双重关键字排序!!让左端点小于右端点,这样可以解决点区间bug。。。
比赛结束后十分钟过得…………pity
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <iostream>
using namespace std;
#define maxn 2000005
#define MOD 1000000007
#define mem(a) memset(a , 0 , sizeof(a))
#define LL __int64
LL n , k;
struct node
{
int val;
int flag;
/*friend bool cmp(node a , node b)
{
return a.val < b.val;
}*/
friend bool operator <(node a , node b)
{
if(a.val == b.val)
return a.flag < b.flag;
return a.val < b.val;
}
}arr[maxn];
struct pointe
{
int left;
int right;
int flag;
}res[maxn] ;
int main()
{
while(scanf("%I64d %I64d" , &n , &k) != EOF )
{
int tmp;
int num = 2 * n;
for(int i = 0 ; i < num ; i ++)
{
scanf("%d" , &tmp);
if(i % 2) arr[i].flag = 1;
else arr[i].flag = 0;
arr[i].val = tmp;
}
sort(arr , arr + num );
int ans = 0;
int pos = 1;
int left = 0;
for(int i = 0 ; i < num ; i ++)
{
if(arr[i].flag) ans--;
else ans++;
if(ans >= k && !left)
{
res[pos].left = arr[i].val;
left = 1;
}
else if(ans < k && left)
{
left = 0;
res[pos].flag = 0;
res[pos++].right = arr[i].val;
}
}
int pos2 = pos;
for(int i = 1 ; i < pos - 1 ; i ++)
{
if(res[i].right == res[i+1].left) res[i].flag = 1 , pos -- ;
}
printf("%d\n" , pos - 1);
res[0].flag = 0;
for(int i = 1 ; i < pos2 ; i ++)
{
//cout << res[i].flag<<endl;
if(!res[i].flag && !res[i-1].flag )
printf("%d %d\n" , res[i].left , res[i].right);
else if(!res[i].flag && res[i-1].flag)
{
printf("%d\n" , res[i].right);
}
else if(res[i].flag && res[i-1].flag )
continue;
else if(res[i].flag && !res[i-1].flag )
printf("%d " , res[i].left);
}
}
return 0;
}