当前位置: 代码迷 >> 综合 >> 1236:区间合并 易错题
  详细解决方案

1236:区间合并 易错题

热度:12   发布时间:2023-10-21 04:49:34.0

首先储存区间,不必多言

struct node
{int a,b;} s[55010];

刚开始的想法是想先把所有的子区间按从小到大的顺序排列。

先排左端点,左端点相同再排右端点

[1,4]

[2,3]

[3,6]

bool compare(node a,node b)
{if(a.a==b.a) return a.b<b.b;elsereturn a.a<b.a;}

然后遍历排好序的所有结点

	for(int i=1;i<n;i++){if(s[i].b<s[i+1].a||s[i].a>s[i].b){printf("no\n");return 0;}}

如果这个区间的右端点小于下一个区间的左端点

那么这两个区间就没有交集,返回false

这里忽略了一种情况

[1,10]

[5,6]

[7,9]

区间2和区间3是没有交集的,按上面的代码会返回false

所以我们应该记录整个区间的左右端点,看这个区间是否与前i-1个区间的总的区间有交集

可以声明两个变量来记录左右端点

	int l=s[1].a;int r=s[1].b;

如果①当前区间的左端点大于前面区间组成的总区间的右端点

或者②当前区间的右端点小于前面组成的总区间的左端点

就是不符合题意的情况了 

因为我们排过序,所以后面的区间的左端点都是满足①的

条件②其实不存在,因为我们排过序了,当前区间的右端点如果小于前面总区间的左端点,也就是当前区间的左端点小于前面总区间的右端点,这个区间会直接被排到前面,然后形成条件①的情况

故只需判断当前区间左端点与总区间的右端点即可

	for(int i=2;i<n;i++){
//		printf("%d %d\n",s[i].a,s[i].b);if(s[i].a>s[i].b){printf("no\n");return 0;}if(s[i].a>r){printf("no");return 0;}r=r>s[i].b?r:s[i].b;}