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\n"); 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\n"); 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

 

posted @ 2016-09-02 19:23  知る奇迹に  阅读(107)  评论(0编辑  收藏  举报