这个题想(qia)了我一上午
才发现
思路明白了就简单了!
兴高采烈.jpg
先来说说思路
贪心
从第一个区间开始融合,即 将搭界、相邻或包含的区间融为一体,我将这样处理过的区间称为大区间
使用计数变量将所有大区间长度相加得出结果
以下是程序详细步骤
输入
使用结构体存储所有未经处理的左端点(以下简称(l))及未经处理的右端点(以下简称(r))
预处理
维护两个变量,存储当前左端点(以下简称(L))及当前右端点(以下简称(R))
(这两个变量是用来存储大区间两端端点的)
将(l)从小到大排序,如果相同,则将(r)从小到大排
重头戏来了
融合
使用(L)和(R)存储第一个(l)和(r),也就是母体初始区间的两个端点
使用循环不断往后找与其搭界、相邻或包含的区间端点,不断更新(R)
最后在没有满足条件的区间时,求出长度,加入计数器中
最后的(L)和(R)就是当前大区间的长度
最后贴上代码
码风丑陋,敬请见谅
#include<iostream>
#include<algorithm>
using namespace std;
struct hhh{
long long l;
long long r;//不开long long见祖宗
};
bool cmp(hhh a,hhh b)//比较函数
{
if(a.l==b.l)//如果l相等
return a.r<b.r;//按照右端点排序
return a.l<b.l;//优先按照左端点排序
}
int main()
{
long long i,n,cnt=0,L,R;//L和R用于存储大区间两端端点
hhh a[100005];
cin>>n;
for(i=0;i<n;i++)
cin>>a[i].l>>a[i].r;//输入
sort(a,a+n,cmp);//排序,做预处理
for(i=0;i<n;)//这里没加i++是因为在循环里,变量"i"有变动
{
L=a[i].l;
R=a[i].r;//第一个未经处理的左右端点
i++;//判断下一个端点
for(;i<n&&a[i].l<=R+1;i++)//按顺序判断下一个端点,R+1是判断相邻
R=max(R,a[i].r);//在这里卡过一次,一定要加max函数,这是包含的情况
cnt+=R-L+1;//将长度放入计数器
//一次循环过后,循环变量"i"已经是下一个未经处理的区间了,不必再加一
}
cout<<cnt;//输出结果
return 0;
}
留个赞再走吧
完结撒花 (。・∀・)ノ