Codeforces Round #613 (Div. 2) E. Delete a Segment

在这里插入图片描述
题意:给定n条线段,如果线段之间有相交的,那么他们就会合并成一个新的线段,现在要删除一个线段,使得去掉后联合后的线段最多。
思路:主要还是参考了大佬的解法(https://www.cnblogs.com/Lanly/p/12181097.html),思维很缜密,反正本菜鸟肯定想道这么细的。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+1;
typedef long long ll;
ll cns,ans;
vector<pair<ll,ll>>v;
bool cmp(const pair<ll,ll> &a,const pair<ll,ll> &b)
{
	return a.first<b.first||(a.first==b.first&&a.second<b.second);
}
int main()
{
	int n,T;
	scanf("%d",&T);
	while(T--)
	{
		v.clear();
		cns=ans=0;
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
		{
			ll l,r;
			scanf("%lld %lld",&l,&r);
			v.push_back({l,r});
		}
		sort(v.begin(),v.end(),cmp);
		ll one=v[0].second,two=-0x3f3f3f3f,cnt=0;
		for(int i=1;i<v.size();++i)
		{
			if(v[i].first>one)//如果当前线段i的左端点大于前面i-1中最大的右端点时,说明线段此时原本就有空位,同时cnt要清零; 
			{
				++cns;
				one=v[i].second;
				two=-0x3f3f3f3f; 
				ans=max(ans,cnt);
				cnt=0;
			}
			else if(two==-0x3f3f3f3f)  two=min(one,v[i].second),one=max(one,v[i].second);//更新一下最大值和次大值 
			else {
				if(v[i].first>two) ++cnt;//表示的是只被当前线段覆盖的区间个数 
				if(v[i].second>=one) 	ans=max(ans,cnt),cnt=0;
				two=max(two,min(one,v[i].second));
				one=max(one,v[i].second);
			}
		}
		ans=max(ans,cnt);
		if(cns+1==n) {
			printf("%lld\n",cns);
			continue;
		}
		printf("%lld\n",ans+cns+1);
	}
}
发布了39 篇原创文章 · 获赞 0 · 访问量 1090

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/103961252