Processing math: 100%

AtCoder Beginner Contest 190 D,E,F問題メモ

AtCoder Beginner Contest 190

グラフ問題って実装でケアレスミスしてもどこがバグってるのかわかりづらい。
ライブラリもっときましょうね。

D - Staircase Sequences

問題

  • 初項が整数、公差が1、項数が有限の等差数列で、和が N となるものの個数を求めよ
  • 1N1012

解法

等差数列の和といえば、初項 a、公差 d、項数 k+1k0)として、総和は (k+1)(a+(a+dk))2 となる。

これが N となればよいので、d=1 を代入して整理すると 2N=(k+1)(2a+k)

各変数は整数なので、2N の約数を列挙して (k+1,2a+k) の組を全て調べればよい。これが a を整数として成り立つなら、そのような等差数列を作れる。

Python3

よく見ると (k+1,2a+k) は必ず偶数・奇数が異なり、またそれさえ満たせば必ず整数解を作れるので、そのことを利用する解法もある。

つまり、N を2で割れるだけ割った結果を M とすると M の約数は必ず奇数、それとかけあわせて 2N となる相方は必ず偶数となる。
あとは約数1個につきどちらが k+1 でどちらが 2a+k かの2通りあるので、M×2 が答えとなる。

E - Magical Ornament

問題

  • N 種類の石がそれぞれ無限個ある
  • 一列に並べて飾りを作る
  • その際「種類 aibi の石は隣り合わせられる」というルールが M 個あり、これ以外は隣りあわせてはいけない
  • K 種類 c1,c2,...,cK の石をそれぞれ1個以上含む飾りを作れるか判定し、作れるなら石の最小個数を求めよ
  • 1N,M105
  • 1K17

解法

始点に戻らなくてよい巡回セールスマン問題。直帰型と呼ぼう。1)

一列に並べるので、ci に含まれるある石からある石へ最短で繋げて、を繰り返すのがよい。
枝分かれしていいならハブのような石の存在を気にしなきゃいけないけど、その必要は無い。

なので、まずは「隣り合わせられる石のルール」1つをグラフの長さ1の辺1本とみなし、ci に含まれる全頂点間の最短距離を求める。
ここで、N 頂点全ての点間の最短距離を求めるのはTLE,MLEなので注意。

そもそも到達できない2頂点があれば、不可能。

求められたら、K 頂点で巡回セールスマン。

Pythonではライブラリが豊富なので、「巡回セールスマン」で検索してもAtCoderでは使えないライブラリとか近似解法の説明とかが出てくる。
「競プロ」とか添えて検索するとよい。

Python3

F - Shift and Inversions

問題

  • 0,1,...,N1 の順列 a0,a1,...,pa1 が与えられる
  • この順列を、k=0,1,...,N1 回シフトさせた数列の転倒数を、各 k について求めよ
  • 1N3×105

解法

転倒数の意味の1つが「正しくない順序(i<j なのに ai>aj)となっているペア数」とわかっていれば、差分に着目すれば比較的簡単。
E問題よりすぐ解けた人も多そう。

まずは、k=0 の時の転倒数を求める。

さて、1個シフトしたらどうなるか。

3 1 4 0 2
    ↓
  1 4 0 2 3

この時、動かす数(3)以外のペアは変わらない。

そして、

  • (3,4) のように従来正しい順序だったペアは必ず転倒する
  • (3,1) のように従来転倒していたペアは必ず正しい順序になる

これで差分が計算できる。

今回は親切なことに順列なので、

  • 従来正しいペアの個数 = 動かす数 ai より大きい数の個数 = Nai1
  • 従来転倒していたペアの個数 = ai より小さい数の個数 = ai

と、ai の値だけからその個数が計算できる。

Python3

1)
最短ハミルトンパスという名前がちゃんとある
programming_algorithm/contest_history/atcoder/2021/0130_abc190.txt · 最終更新: 2021/02/03 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0