版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/A7_RIPPER/article/details/82078412
题目大意:
给你n的区间,要求输出n-1个区间的最长交集的长度(也就是需要删除一个区间)
解题思路:
当时没啥头绪,还以为是和容斥有关,主要是不知道如何求公共交集的长度。
今天看了下网上的代码,大致理解了过程。
对于n个区间来说,它们公共的交集长度就是最大左边界和最小右边界的差的绝对值。注意这个交集是这n个区间的子集合,当时没理解这一点,以为是只要是交集就行。那么保存下所有的左边界和右边界,每次删除一个区间,然后找剩下左边界最大和右边界最小即可。
代码如下:学习了一个新容器multiset,可以保存重复元素。
#include<iostream>
#include<cstdio>
#include<fstream>
#include<set>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<iomanip>
#include<cstdlib>
#include<list>
#include<queue>
#include<stack>
#include<algorithm>
#define inf 0x3f3f3f3f
#define MOD 1000000007
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define meminf(a) memset(a,inf,sizeof(a))
//vector ::iterator it;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);
//freopen("test.txt","r",stdin);
// freopen("output.txt","w",stdout);
vector<pair<int,int> > v;//保存区间
multiset<int> L,R;//多重集合,保存左右边界
int n;
cin>>n;
for(int i=0;i<n;i++)
{
int l,r;
cin>>l>>r;
v.push_back({l,r});//存放区间,注意是花括号
L.insert(l);R.insert(r);//存放边界
}
int ma=0;
for(int i=0;i<n;i++)
{
int l=v[i].first,r=v[i].second;
L.erase(L.find(l));R.erase(R.find(r));//删除这个区间
int ml=*(L.rbegin()),mr=*(R.begin());//找最大左边界好最小右边界
ma=max(ma,mr-ml);//更新最大值
L.insert(l);R.insert(r);//记得把删除的区间放回去
}
cout<<ma<<endl;
}
GNU c++ 5.1.0报编译错误,换成GNU C++17就AC了。