题目描述
周老师无聊时乱写了 n 个区间,但处女座的他随后又想将 n 个区间整理合并,但他发现区间太多了,于是他想请你帮帮他
输入
每次测试输入多组数据(小于100组),对于每组输入数据:
第一行为 n ,代表 n 个区间
接下来 n 行,每行两个数 s , t 代表区间 [s,t]
0 < n < 15000
0 <= s <= t < 10000000
输出
第一行输出一个数字 q ,代表合并后剩余的区间个数
随后 q 行 按从小到大的顺序输出区间
样例输入 Copy
3
2 4
1 3
7 7
样例输出 Copy
2
1 4
7 7
分析:
此题的基本思路是排序,然后再合并。具体的来说呢,就是先按s排序,大的s放后面。如果s相等,那么就将t排序。大的t放后面。
排序后,依次遍历,如果前一个区间的t大于后一个区间的s,那么他们可合并。
本题的题的数据较大,需要快排
#include"stdio.h"
#include"string.h"
typedef struct
{
long long left;
long long right;
} Region;
void swap(Region x[],long long start,long long end)
{
Region t;
t=x[start];
x[start]=x[end];
x[end]=t;
}
long long location(Region crows[],long long start,long long end)
{
Region Key;
Region T;
Key=crows[start];
while(start<end)
{
//这里按left排序
while(start<end&&crows[end].left>Key.left)
end--;
//如果left相等,则看right,注意,必须〉=,如果没有=,则有可能会陷入死循环。
//例如,3 1 3 1 3 5 5 。这组数据没有=,就会陷入死循环。因为end无法--
while(start<end&&crows[end].left==Key.left&&crows[end].right>=Key.right)
end--;
swap(crows,start,end);
while(start<end&&crows[start].left<Key.left)
start++;
while(start<end&&crows[start].left==Key.left&&crows[start].right<=Key.right)
start++;
swap(crows,start,end);
}
return start;
}
void qsort(Region crows[50000],long long low,long long high)
{
long long locale;
if(low<high)
{
locale=location(crows,low,high);
qsort(crows,low,locale-1);
qsort(crows,locale+1,high);
}
}
int main()
{
long long N;
long long i,j,k;
Region a[15001],T;
while(~scanf("%lld",&N))
{
for(i=0; i<N; i++)
scanf("%lld%lld",&a[i].left,&a[i].right);
qsort(a,0,N-1);
j=0;
for(i=1; i<N; i++)
{
if(a[i].left<=a[j].right)
{//这里要注意,还要判断一下,他们的right的大小,才能决定是否赋值过去。
if(a[j].right<=a[i].right)
a[j].right=a[i].right;
continue;
}
else
{
j++;
a[j]=a[i];
}
}
printf("%lld\n",j+1);
for(i=0; i<=j; i++)
printf("%lld %lld\n",a[i].left,a[i].right);
}
}