Pocalaメモ

アウトプット用のなにか

AtCoder Beginner Contest 125 の解説

久しぶりに全完したような気がしますが、酷いミスが多すぎて喜べません…考察はすぐに生えたのにミスを量産してしまいました。具体的には


C…forの範囲をi <= n にしていてWA。正しくは i < n。
D…総和 - 最小*2 の所を、総和 - 最小 にしてしまった。

です。いやこれで15分ロスしてるんですが…悲しい…ということで解説です

A

T/A*Bを出力すれば良いです。

B

問題文に「一つも選ばなくてもよいです」と書いてある。宝石を取るメリットがある時(Vi > Ciのとき)は取っていき、その総和を計算すればいいです。

C

i番目を選んで数字を好きなものに変えるとします。
その時、「i番目以外全ての数字の最大公約数」と同じ値にしてあげるのが一番いい手です。例えば 1 10 10 10 10 で、1番目の数字「1」を書き換える場合、他の4つの最大公約数の「10」に書き換えてあげると答えは10になります。

よく考えてみると「i番目を書き換える時の最大の値は、i番目を除いた全ての数字の最大公約数」ということが分かります。一つの数字だけ無視できる、みたいな感じになります。
なのでこの問題は、「どの数字を無視すれば、最大公約数が最大になるか」のような問題にもっていけます。

f:id:kemingsurface:20190427222909p:plain

このように、点線の丸以外の全ての数字の最大公約数は、左部分と右部分に分けてgcd(左の部分, 右の部分)と計算することができます。配列の扱いに十分注意して下さい。

D

Dのほうが簡単だったかも…?

隣り合った二つのプラマイを反転させる時、
① +と-→-と+(左右が入れ替わる!)
② -と-→+と+(マイナスを消した)
というふうなパターンに分けることができます。

  1. - + + - + のようなものは、①のパターンを使いまくることで右に寄せることができます。

②番を使うことでマイナスを消していけますが、一度に消せるのは2つずつなので、マイナスの数が
・偶数…全てプラスにできる
・奇数…ひとつだけマイナスになってしまう
という風になります。①番を使いまくれば一番被害が少ない数字(絶対値が一番小さい数字)をマイナスにすることで、最大値にすることができます。


はい。急いで書いたのでクオリティが低いです。すいません。