こんにちは, Shinoryoです.
今回は東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 304)を, Pythonで解いてみた結果を書き連ねていこうと思います.
Tokio Marine & Nichido Fire Insurance Programming Contest 2023(AtCoder Beginner Contest 304) - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
A - First Player
Aの最小値とそのインデックス(A_min_index
)を取得し, A_min_index
以降の要素を出力した後, A_min_index
より前の要素を出力すればよいです.
# 入力 | |
N = int(input()) | |
S = [] | |
A = [] | |
for _ in range(N): | |
S_i, A_i = input().split() | |
S.append(S_i) | |
A.append(int(A_i)) | |
# Aの最小値とそのインデックスを取得 | |
A_min = min(A) | |
A_min_index = A.index(A_min) | |
# 出力 | |
# A_min_index以降の要素を出力 | |
for i in range(A_min_index, N): | |
print(S[i]) | |
# A_min_indexより前の要素を出力 | |
for i in range(A_min_index): | |
print(S[i]) |
B - Subscribers
# 入力 | |
N = list(input()) | |
# 文字列のまま切り捨ての操作 | |
for i in range(len(N) - 3): | |
N[- (i + 1)] = "0" | |
# 出力 | |
print("".join(N)) |
C - Virus
下の図のように, 人の間の距離が
このようにくっついた人同士の集合というのを考えることができます.
もし
このような操作は例えば, Union Findを用いて実装することができます. 最初は1つひとつバラバラな要素(人)が用意されます. そして, 「2つのまとまり(人)をつなげる」という操作を繰り返し, 最終的にある要素がどの集合に属しているかを管理していくアルゴリズムです.
「2つのまとまり(人)をつなげる」という操作に時間計算量が
以下の例では, nkmk様による「PythonでのUnion-Find(素集合データ構造)の実装と使い方」(https://note.nkmk.me/python-union-find/)に掲載されているUnion Findのコードを使用しています.
from itertools import combinations | |
# Union Find | |
# https://note.nkmk.me/python-union-find/ | |
class UnionFind(): | |
def __init__(self, n): | |
self.n = n | |
self.parents = [-1] * n | |
def find(self, x): | |
if self.parents[x] < 0: | |
return x | |
else: | |
self.parents[x] = self.find(self.parents[x]) | |
return self.parents[x] | |
def union(self, x, y): | |
x = self.find(x) | |
y = self.find(y) | |
if x == y: | |
return | |
if self.parents[x] > self.parents[y]: | |
x, y = y, x | |
self.parents[x] += self.parents[y] | |
self.parents[y] = x | |
# 入力 | |
N, D = list(map(int, input().split())) | |
position = [list(map(int, input().split())) for _ in range(N)] | |
# Union Find生成 | |
infection_connection = UnionFind(N) | |
# 全ての2人組の組み合わせでループし、その間の距離D以下なら、その2つをUnionFind.union()でくっつける | |
for i, j in combinations(range(N), 2): | |
if (position[i][0] - position[j][0]) * (position[i][0] - position[j][0]) + (position[i][1] - position[j][1]) * (position[i][1] - position[j][1]) <= D * D: | |
infection_connection.union(i, j) | |
# index 0の人が属する集合の、Union Find上のrootを取得 | |
root = infection_connection.find(0) | |
# Union Find上のrootが一致している人は、同じ集合に属していて感染していることになる | |
for i in range(N): | |
if infection_connection.find(i) == root: | |
print("Yes") | |
else: | |
print("No") |
Union Findは, 以下のAtCoder Beginner Contestでも登場しています.
AtCoder Beginner Contest 214をPythonで解く
こんにちは, Shinoryoです. 今回は AtCoder Beginner Contest 214 を, Pythonで解いてみた結果を書き連ねていこうと思います. AtCoder Beginner Contest 214 - AtCoder AtCoder is...
ユニークビジョンプログラミングコンテスト2023 春 (AtCoder Beginner Contest 300)をPythonで解く
こんにちは, Shinoryoです. 今回は ユニークビジョンプログラミングコンテスト2023 春 (AtCoder Beginner Contest 300) を, Pythonで解いてみた結果を書き連ねていこうと思います. ユニークビジョンプログラミングコンテスト...
D - A Piece of Cake
左から
ある苺の座標を
その位置の情報をもとに, (ピースのID,そこに乗っている苺の数)のタプルを, 苺の数の多い順に出力することができます.
- 苺の乗っているピースが
(ピースの総数)よりも少ない場合
となります. - 苺の乗っているピースが
(ピースの総数)と等しい場合
としては先ほどのタプルのリストの最も後ろ側を参照します.
二分探索にはbisectモジュールを, (ピースのID,そこに乗っている苺の数)のタプルを苺の数の多い順に出力するのにはCollectionsモジュールを使用することができます.
from bisect import bisect_left | |
from collections import Counter | |
# 入力 | |
W, H = map(int, input().split()) | |
N = int(input()) | |
strawberries = [list(map(int, input().split())) for _ in range(N)] | |
A = int(input()) | |
a_list = list(map(int, input().split())) | |
a_list.append(W) | |
B = int(input()) | |
b_list = list(map(int, input().split())) | |
b_list.append(H) | |
# 左からX列目、下からY行目にあるピースのIDを(X,Y)と定める | |
# 苺が乗っているピースのIDを二分探索で調査 | |
strawberries_location = [bisect_left(a_list, strawberries[i][0]) + bisect_left(b_list, strawberries[i][1]) * (10**6) for i in range(N)] | |
# (ピースのID,そこに乗っている苺の数)のタプルを、苺の数の多い順に出力 | |
strawberries_count = Counter(strawberries_location).most_common() | |
# mを求める | |
if len(strawberries_count) < (A + 1) * (B + 1): | |
m = 0 | |
else: | |
m = strawberries_count[-1][1] | |
# Mを求める | |
M = strawberries_count[0][1] | |
# 出力 | |
print(m, M) |
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - 東京海上日動プログラミングコンテスト2023(AtCoder Beginner Contest 304)」
Editorial - Tokio Marine & Nichido Fire Insurance Programming Contest 2023(AtCoder Beginner Contest 304)
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
- nkmk様による「PythonでのUnion-Find(素集合データ構造)の実装と使い方」
PythonでのUnion-Find(素集合データ構造)の実装と使い方 | note.nkmk.me
PythonでのUnion Findデータ構造(素集合データ構造)の実装とその使い方を説明する. まずはじめに最終形のクラスとその使い方のサンプルコードを示し, 後半で素朴な実装からいくつかの工夫を加えて最終形に至るまでを説明する. Union Find(素集合データ構造)の概要 PythonでのUnion Findの実装例 サンプルコードのクラス...
- Wakasugi Tatsuroh様による「Pythonで二分探索を行うライブラリ「bisect」」
Pythonで二分探索を行うライブラリ「bisect」 - Qiita
趣味で競プロをやるようになり, Atcoderの問題を何問か解いているのだが, やっている内に覚えないといけないこともいくつかあるわけで. その内の一つに二分探索というアルゴリズムを使うという場面を多く見てきたため, 自分が今よく利用して...
- e様による「【Python】リストの要素の数え上げ, collections.Counterの使い方」
【Python】リストの要素の数え上げ, collections.Counterの使い方 - Qiita
はじめに 今回はPythonのcollections.Counter()についてまとめます. AtCoderのPython3.4.3と3.8で動作確認済みです. collections.Counterについて collec...
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)