计蒜客- Trace 二分

链接:https://nanti.jisuanke.com/t/31459

题意:有n次海浪,每次海浪会产生两段轨迹(0,y)到(x,y)和(x,0)到(x,y),后面的海浪会将前面的在(0,0)到(x,y)之间区域的海浪轨迹覆盖掉,问最后剩余的轨迹长度。保证后面的海浪不会完全覆盖其他海浪。

思路:根据题意,后面的点要么比前面的点高,要么比他们长。从后向前统计,用set记录每一个已经统计过长度的线段。统计一条线段的有效长度,要减去被覆盖的部分,方法:找到已经统计过的线段中 比新线段小的所有线段的最大值(用二分找),这个值就是新线段被覆盖的部分,减去这个值得到有效值,如果没有,就表明新线段没有被覆盖,直接统计。

代码:

#include <iostream>    
#include <algorithm>
#include <vector>
#include <set>
#define ll long long 
#define maxn 50009
#define rep1(i,a,b) for(int i=a;i<=b;i++)
#define rep2(i,a,b) for(int i=a;i>=b;i--)
using namespace std;

vector<int> xvec, yvex;
int n;

ll callength(vector<int> vec) {
    set<int> st;
    ll ans = 0;
    set<int>::iterator it;

    rep2(i, n - 1, 0) {
        it = st.lower_bound(vec[i]);
        if (it == st.begin()) {
            ans += vec[i];
        }
        else {
            it--;
            ans += vec[i] - *it;
        }
        st.insert(vec[i]);
    }

    return ans;
}

int main() {
    int x, y;

    scanf("%d",&n);
    rep1(i, 1, n) {
        scanf("%d%d", &x, &y);
        xvec.push_back(x);
        yvex.push_back(y);
    }

    printf("%lld", callength(xvec) + callength(yvex));

    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/the-way-of-cas/p/9648393.html