【ACM-ICPC 2018 徐州赛区网络预赛】G题 Trace ---- 思维

版权声明:本文为博主原创文章,转载请预先通知博主(〃'▽'〃)。 https://blog.csdn.net/m0_37624640/article/details/82631335

题目链接

做法:

  • 很好的一个思维题
  • 题意向我们保证当前的浪花的痕迹不会完全覆盖之前的浪花的痕迹,所以我们要逆向思维,倒着来,从最后的浪花的痕迹往前思考。如果能找到第一个比当前浪花痕迹短的,那么保留的痕迹就是当前的痕迹-第一个比当前短的浪花的痕迹
  • 否则,它的痕迹如果是最小的,那么直接加入答案。
  • 这个题用STL写的话,利用一个set,然后二分查,就非常容易理解。

AC代码:

#include<bits/stdc++.h>
#define IO          ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb(x)       push_back(x)
#define sz(x)       (int)(x).size()
#define sc(x)       scanf("%d",&x)
#define pr(x)       printf("%d\n",x)
#define abs(x)      ((x)<0 ? -(x) : x)
#define all(x)      x.begin(),x.end()
#define mk(x,y)     make_pair(x,y)
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const double PI = 4*atan(1.0);
const int maxm = 1e8+5;
const int maxn = 1e5+5;
const int INF = 0x3f3f3f3f;
set<int> s;
ll solve(vector<int> e)
{
    s.clear();
    int n = e.size();
    ll ans = 0;
    for(int i=n-1;i>=0;i--)
    {
        auto it = s.lower_bound(e[i]);
        if(it == s.begin()) ans+=e[i];//如果当前值是最小的那么直接加
        else{
            it--; //找第一个比当前值小的
            ans += e[i]-*it;
        }
        s.insert(e[i]);
    }
    return ans;
}
int main()
{
    #ifdef LOCAL_FILE
    freopen("in.txt","r",stdin);
    #endif // LOCAL_FILE
    vector<int> x,y;
    int n;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        ll xx,yy;
        cin>>xx>>yy;
        x.pb(xx);
        y.pb(yy);
    }
    cout<<solve(x)+solve(y)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37624640/article/details/82631335
今日推荐