https://beta.atcoder.jp/contests/arc101/tasks/arc101_a
考察過程
1. 最適な動きを考えてみると、負に行って正に行って終えるか、正に行って負に行って終えるのが最適
2. どれだけ負に行くかであるが、負のろうそくをi個経由した場合は正のろうそくをK-i個通る必要がある
3. iを固定するとO(1)で必要な移動量がわかるので、iを全探索すればいい
解法
https://beta.atcoder.jp/contests/arc101/submissions/3081172
配列Xをそのまま使わず、正prと0以下miに分けて使う。
prとmiは最初に0を入れておき、miの方は-X[i]で入れてソートしておく。
これで、
pr[i] := 原点から正の方向にi個ろうそくを通過するのにかかる時間
mi[i] :=原点から負の方向にi個ろうそくを通過するのにかかる時間
が得られる(最初に0を入れておくのはpr[0]とmi[0]を用意するため)。
負の方向でi個ろうそくを通って、正の方向にK-i個ろうそくを通るとすると、
負の方向は往復の時間がかかるため、必要な時間はmi[i]*2+pr[K-i]となる。
これでiを全探索して、必要な時間の最小値を求める。
負の方向移動して、正の方向移動する方も試そう。
int N, K, X[101010]; vector<int> mi, pr; //--------------------------------------------------------------------------------------------------- void _main() { cin >> N >> K; rep(i, 0, N) cin >> X[i]; mi.push_back(0); pr.push_back(0); rep(i, 0, N) { if (X[i] <= 0) mi.push_back(-X[i]); else pr.push_back(X[i]); } sort(all(mi)); sort(all(pr)); int n = mi.size(); int m = pr.size(); int ans = inf * 2; rep(i, 0, n) { int j = K - i; if (0 <= j and j < m) chmin(ans, mi[i] * 2 + pr[j]); } rep(i, 0, m) { int j = K - i; if (0 <= j and j < n) chmin(ans, pr[i] * 2 + mi[j]); } cout << ans << endl; }