【AtCoder】ABC 462 E - Alternating Costs

実行時間制限: 2 sec / メモリ制限: 1024 MiB / Difficulty: 1226 / NoviSteps: 1Q / 配点: 450 点
問題概要
二次元平面上にコマが置かれており、はじめコマは座標 にある。
これから、以下の操作を 回以上何回でも行うことができる。
- 今コマがある座標を として、座標 のいずれかにコマを移動させる。
回目に行う操作にかかるコストは の偶奇によって異なり、それぞれ以下の通り。
- が奇数のとき:今コマがある座標を として、座標 に移動させる場合のコストは 、座標 に移動させる場合のコストは である。
- が偶数のとき:今コマがある座標を として、座標 に移動させる場合のコストは 、座標 に移動させる場合のコストは である。
コマを座標 に移動させるために必要なコストの総和の最小値を求めよ。 個のテストケースが与えられるので、それぞれについて答えを求めること。
制約
- 入力される値は全て整数
考察
対称性より、 として考えてよい。
まずは斜めに進む
手数の偶奇で移動コストが変わるのが面倒くさいので、まずは2手セットで考えると、
- 横 + 縦:
- 縦 + 横:
となるので、2手で斜め方向に1マス進むときの最小コストは である。
この移動方法で、できる限り目的地 に近づきたい。 とすると、 回斜め移動を行って まで到達でき、その時の移動コストは である。
残りは縦か横に進む
残りの距離は である。 ここでも、縦 or 横方向に2マスずつ進むことを考える。
横方向に2マス進む場合、例えば以下の2通りの移動方法が考えられる。
- 横 + 横:
- 斜め右上 + 斜め右下:
これは縦方向に2マス進む場合も同様である。
したがって、縦 or 横方向に2マス進むときの最小コストは である。
この移動方法を使えるのは、 回であり、そのときの移動コストは である。
が奇数のときは最後に1マス進む
が偶数であればこれで議論は終わりなのだが、奇数の場合は最後にもう1マス進む必要がある。
ここで、「横1マスなら 、縦1マスなら 」と安易にしてはダメ(自戒)。
例えば、 に横に1マス進むときの移動方法は以下の2通りある。
- 普通に横に1マス進む:
- :
したがって、横に1マス進むときの最小コストは である。
同様に、縦に1マス進むときの最小コストは と書ける。
以上をまとめると、求める最小コストは以下のように計算できる。
実装例
実装時はlong long型で計算する必要があることに注意。
1.#include <bits/stdc++.h>2.using namespace std;3. 4.using ll = long long;5. 6.// ======================================== //7. 8.ll solve() {9. ll A, B, X, Y;10. cin >> A >> B >> X >> Y;11. 12. ll x = abs(X), y = abs(Y);13. 14. ll diagonal = 2 * min(A, B);15. ll axis = min(A + B, 4 * min(A, B));16. 17. ll cost = diagonal * min(x, y) + axis * (abs(x - y) / 2);18. if (abs(x - y) % 2 == 1) {19. if (x > y) cost += min(A, 3 * B);20. else if (x < y) cost += min(3 * A, B);21. }22. 23. return cost;24.}25. 26.int main()27.{28. int T;29. cin >> T;30. 31. while (T--)32. {33. cout << solve() << endl;34. }35. 36. return 0;37.}実装時間: 40 分
コメント
特別なアルゴリズムを必要とせず考察のみで解ける、ARCっぽい問題。
最後の1マス進むときのコストの考察をし忘れて1ペナ。





