ABC264の振り返り(A, B, C, D, E)
振り返りです。
import copy def test_all(f): for i, data in enumerate(eval(f"test_data{f.__name__[0]}")): exp = data["out"] ans = f(*copy.deepcopy(data["in"])) result = "AC" if exp == ans else "WA" print(f"{i+1} {result}: expected: {exp}, output: {ans}")A - "atcoder".substr()
略
B - Nice Grid
やってみよう!
B
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
解法がパッと思いつかなかったので、設問のグリッドをつくりました。
import numpy as np def B(R, C): g = [[0]] for i in range(7): g = np.pad(g, 1, constant_values=0 if i % 2 else 1) return "black" if g[R - 1, C - 1] else "white" print(B(3, 5)) # black print(B(4, 5)) # white結果:提出 #35087826
自由欄
解説を見る
解説ではチェビシェフ距離という概念に言及しています。
初見なので軽く調べてみました。
- チェビシェフ距離 - Wikipedia
- ディープラーニングで用いられる6つの距離計算 | SiTest (サイテスト) ブログ
- このデータセットにはどの距離を用いればよいの??~ユークリッド距離・マンハッタン距離・チェビシェフ距離・マハラノビス距離~ \| データ化学工学研究室(金子研究室)@明治大学 理工学部 応用化学科
ディープラーニング関連の文脈で紹介されているのが興味深いですね。
それはさておき、実装はこんな感じ。
結果:提出 #35089398
参考までに、3つの「距離1」を図示するとこんな感じです。
# 縮小表示 import numpy as np from matplotlib import pyplot as plt fig, ax = plt.subplots(figsize=(8, 3)) angle = np.linspace(0, 2 * np.pi, 100) x = np.cos(angle) y = np.sin(angle) ax.plot(x, y, label="Euclidean distance") x = np.linspace(1, -1, 50) y = 1 - np.abs(x) ax.plot( np.concatenate([x, x[::-1]]), np.concatenate([y, -y]), label="Manhattan distance" ) ax.plot([1, -1, -1, 1, 1], [1, 1, -1, -1, 1], label="Chebyshev distance") ax.spines[:].set_position("center") ax.axis("equal") ax.legend(loc="upper left", bbox_to_anchor=(0, 1)) plt.show()自由欄
C - Matrix Reducing
やってみよう!
C
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
コンテスト中にACした回答が以下。
行・列方向でBがサブセットになるようにAを抽出できればオッケーでしょう、という考え方です。
結果:提出 #34007950
実は不正解だった😭
後日(というかこの記事を書きながら)改めてACしたコードを提出してみるとWAになりました。
どうやらコンテスト後に追加されたテストケースのようです。
で、改めて提出したコードについて考えてみると以下のような問題がありました。
No
のケースでYes
としてしまう
以下のようなケースでは、行・列いずれの方向でもBはAのサブセットになるのでYes
を返してしまいます。
Yes
のケースでNo
としてしまう
以下のようなケースではAの1行目と2列目を削除するとBに一致しますが、コード上はまずAの1行目を保持して2行目を削除してしまうので"No"を返すことになります。
元々思いつきで実装してみたらACだったという感じで自信はなかったのですが…
全然ダメやん😇
自由欄
解説を見る
という訳で、暫く考えてもいい方法が思いつかないので解説を見ます。
解説 by leaf1415では全探索の解法を紹介しています。
なかなかの力技ですが、「制約の小さいC問題」は全探索が第一候補でしたね…
無事AC
結果:提出 #35155638
ちなみに14行目のnp.all
をnp.allclose
とすると、ACにはなるものの時間ギリギリになってしまいました(提出 #35155358)。
その他の解説
ここまでやって解説 by kyopro_friendsを見るとまんま同じでした。
解説 by hamayanhamayanも全探索。
解説 by cirno3153はよくわからん。
自由欄
D - "redocta".swap(i,i+1)
やってみよう!
D
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
バブルソートの実装です。
正直、D問題のレベルではないと思います。
(バブルソートってどんなんだっけとコンテスト中にググったのは内緒です。)
結果:提出 #34012391
解説を見る
なんて調子に乗りながら解説を見ると、幅優先探索だったり転倒数だったり小難しい解法が紹介されています。
という訳でちょっと調べてみました。
どうやらこの問題で求める値のような数を転倒数というらしいです。
そしてバブルソートでは$O(N^2)$掛かる計算量が、Binary Indexed Tree (BIT)というデータ構造を使えば$O(N \log N)$で求められるらしいです。(幅優先探索は知らん)
- 参考
ちなみに、BITで文字通りBinary Indexを実装するために必要な最下位ビット(least significant bit: LSB)を求めるための2の補数表現のpythonでの考え方については、ABC262のA問題でも解説しました。
意外なところで繋がるもんですね。
BITを使った解法
以下は基本的に上記サイトを参考に実装し(パクリ)ました。
ただパクるだけではつまらないので、初期値としてiterable
を受け取れたり、基本的なlistとしても操作できるように特殊メソッドを追加しました。
結果:提出 #35266096
自由欄
E - Blackout 2
やってみよう!
E
関数を完成させて「Run」ボタンをクリックしよう!
自由欄
try
ムズかった…
コンテスト中にACならず、翌日に解説を読んでもうまく実装できず寝かしておりました💦
改めて解説のエッセンス(逆から見る、発電所を全て同一視)を取り込んで、頑張って幅優先探索で実装したのが以下。
from collections import deque def E(N, M, UV, X): UV = [[0 if u > N else u, 0 if v > N else v] for u, v in UV] edges = [[] for _ in range(N + 1)] for i in set(range(1, len(UV) + 1)) - set(X): u, v = UV[i - 1] if u == 0: continue edges[u].append(v) edges[v].append(u) ret = [0] # 電気が通っている都市の数 passed = set([0]) # 発電所 q = deque([0]) # 発電所から探索スタート for x in X[::-1]: # BFS while q: for i in edges[q.pop()]: if i in passed: continue ret[-1] += 1 passed.add(i) q.append(i) ret.append(ret[-1]) # 電線を繋ぐ u, v = UV[x - 1] if u == 0: ## 両方発電所 q = False continue edges[u].append(v) edges[v].append(u) c = set([u, v]) p = passed & c if len(p) == 1: nxt = (c - p).pop() ret[-1] += 1 passed.add(nxt) q = deque([nxt]) else: q = False continue return "\n".join(map(str, ret[:-1][::-1])) test_all(E)結果:#35422923
自由欄
DSU -- Union-Find --
さて、解説ではなにやらAtcoder提供のライブラリを使用してサクッと実装しています。ズルい!!
そんなズルい武器はどんどん自分のものにしていきたいところです。
という訳で以下DSU(Disjoint Set Union、または素集合データ構造:disjoint-set data structure、またはunion–find data structure)を使って解いてみます。(呼び名が多い…)
- 参考
結果:#35458365
無事AC。こんなシンプルな実装で解けてしまうとは…!恐るべしUnion-Find
自由欄
まとめ
学びの多い回でした。
以上!