• AIM Tech Round 3 (Div. 2) B 数学+贪心


    http://codeforces.com/contest/709

    题目大意:给一个一维的坐标轴,上面有n个点,我们刚开始在位置a,问,从a点开始走,走n-1个点所需要的最小路程。

    思路:我们知道,如果你一会儿走左一会儿左右,最后访问n-1个点一定只会让距离更长的,所以我们的策略是刚开始全都往一端走,然后访问完n-1个点即可。刚开始我是分类讨论的。。。讨论的要死了。。。不过后来看了一下别人的代码,发现虽然思路是对的,但是过程想麻烦了。 具体看代码吧。

    我的乱七八糟的分类讨论

    //看看会不会爆int! 或者绝对值问题。
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define ALL(a) a.begin(), a.end()
    const int maxn = 100000 + 5;
    const LL inf = 1e18;
    int n;
    LL a;
    LL x[maxn];
    
    int main(){
        cin >> n >> a;
        LL tmp = a;
        for (int i = 0; i < n; i++) scanf("%lld", x + i);
        if (n == 1) {printf("0
    "); return 0;}
        sort(x, x + n); x[n] = inf;
        int pos = lower_bound(x, x + n, a) - x;
        LL lb = a - x[0], rb = x[n-1] - a;
        LL ans = inf;
        if (pos == 0) ans = min(ans, rb - x[n - 1] + x[n - 2]);
        else if (pos == 1){
            ans = min(rb, lb * 2 + rb - x[n - 1] + x[n - 2]);
            ans = min(2 * abs(rb - x[n - 1] + x[n - 2]) + lb, ans);
        }
        else if (pos == n - 1) {
            if (x[pos] == a) ans = min(ans, lb - x[1] + x[0]);
            else {
                ans = min(lb, rb * 2 + lb - x[1] + x[0]);
                ans = min(ans, 2 * (lb - x[1] + x[0]) + rb);
            }
        }
        else if (pos == n) ans = min(ans, lb - x[1] + x[0]);
        else {
            ans = min(2 * lb + rb - x[n - 1] + x[n - 2], 2 * rb + lb - x[1] + x[0]);
            ans = min(ans, 2 * (lb - x[1] + x[0]) + rb);
            ans = min(ans, 2 * (rb - x[n - 1] + x[n - 2]) + lb);
        }
        cout << ans << endl;
        return 0;
    }
    View Code

    另一种写法,很简便

    //看看会不会爆int! 或者绝对值问题。
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define ALL(a) a.begin(), a.end()
    const int maxn = 100000 + 5;
    const LL inf = 1e18;
    int n;
    LL a;
    LL x[maxn];
    
    int main(){
        cin >> n >> a;
        for (int i = 0; i < n; i++) scanf("%lld", x + i);
        if (n == 1) {printf("0
    "); return 0;}
        sort(x, x + n); x[n] = inf;
        LL ans = min(abs(x[0] - a), abs(x[n - 2] - a)) + x[n - 2] - x[0];
        LL tmp = min(abs(x[1] - a), abs(x[n - 1] - a)) + x[n - 1] - x[1];
        cout << min(ans, tmp) << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    并发队列 – 无界阻塞队列 LinkedBlockingQueue 原理探究
    并发队列 – 有界阻塞队列 ArrayBlockingQueue 原理探究
    Java回调机制解读
    一张图看懂encodeURI、encodeURIComponent、decodeURI、decodeURIComponent的区别
    uva 111 History Grading
    hdu 2546 饭卡
    hdu 2602 Bone Collector
    uva 10720 Graph Construction
    uva 10716 Evil Straw Warts Live
    uva 10070 Camel trading
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5835401.html
Copyright © 2020-2023  润新知