Codeforces Round #506 (Div. 3)C-Maximal Intersection


STL算什么!!!还是那句话!!!
数组模拟世间万物!!!!!!!!!!!!!!!!!
好吧,前缀后缀方法&stl法

前缀后缀:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define s second
#define f first
const int N = 1e6;
const int INF = 1e9;
int ans = 0;
pair<int,int> a[N], pre[N], suf[N];//prefix前缀,suffix后缀
int32_t main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i].f>>a[i].s;

    pre[0].f=suf[n+1].f=0;//等会用于比大小的
    pre[0].s=suf[n+1].s=INF;//等会用于比大小的
    for(int i=1;i<=n;i++){
        pre[i].f=max(pre[i-1].f,a[i].f);//表示前i个数中,最大的左端点的坐标
        pre[i].s=min(pre[i-1].s,a[i].s);//表示前i个数中,最小的右端点的坐标
    }
    for(int i=n;i>=1;i--){
        suf[i].f=max(suf[i+1].f,a[i].f);//表示从第i个数到第n个数中,最大的左端点的坐标
        suf[i].s=min(suf[i+1].s,a[i].s);//表示从第i个数到第n个数中,最小的右端点的坐标
    }
    for(int i=1;i<=n;i++){
        int l=max(pre[i-1].f,suf[i+1].f);//除去第i个线段后,最大的左端点的坐标
        int r=min(pre[i-1].s,suf[i+1].s);//除去第i个线段后,最小的右端点的坐标
        ans = max(ans, r - l);
        }
    cout << ans;
    //system("pause");
    return 0;
}

简简单单三个循环~前缀后缀的思想
BUT!!!!!!!!!!!!!!!
还有个方法!!!!!!!!!!!!

是博主shuaihui写的,
最后一个for循环里的判断:
如果最大的左端点/最小的右端点现在和我们枚举准备(删掉)的那个线段端点重合了,那么就把那个左端点变成第二大的/右端点变成第二小的/有了这个方法,我们还可以考虑,求一下n-m条线段重合的最大交集
STL方法


 #include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
const int INF = int(1e9);
#define int long long
multiset<int>a, b;
int n, l[N], r[N],ans,ans1;
int32_t main(){
    cin >> n;
    for(int i=0;i<n;i++){
        cin >>l[i] >> r[i];
        a.insert(l[i]);
        b.insert(r[i]);
    }
    for (int i = 0; i < n;i++){
        a.erase(a.find(l[i]));
        b.erase(b.find(r[i]));
        ans = max(ans, *b.begin() - *a.rbegin());
        a.insert(l[i]);
        b.insert(r[i]);
    }
    
    cout << ans;

    //system("pause");
    return 0;
}

这个题用STL耗时真的是太长了
感觉怕怕的
跟上面的思路是一样的,
因为我们求交集的方法就是
右端点的最小值-左端点的最大值
然后现在就是排除每一个线段,算交集,就这么一趟求下来
multiset自带排序功能,很方便
但是注意一个问题
a.erase(a.find(l[i]));
a.erase(l[i]);
这两者是不一样的,后者会把所有的这个数值的数全都删掉,set也是这样,但是这道题的情景是
每次删除一条线段,看看剩下n-1条的交集是谁
所以必须要用上面的方法,只删除那一个,multiset里面可以包含好多相同的元素,也会排序
比如1,2,3,4,4,4,4,4,4,这样~

还有一道二维题,是一个道理,下一篇博客写

猜你喜欢

转载自www.cnblogs.com/guaguastandup/p/10356064.html