こんにちは, Shinoryoです.
今回はユニークビジョンプログラミングコンテスト2023 夏 (AtCoder Beginner Contest 312)を, Pythonで解いてみた結果を書き連ねていこうと思います.
UNIQUE VISION Programming Contest 2023 Summer(AtCoder Beginner Contest 312) - AtCoder
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
A - Chord
入力された文字列が, {"ACE", "BDF", "CEG", "DFA", "EGB", "FAC", "GBD"}
のset
型に含まれるかを判定すればよいです.
if input() in {"ACE", "BDF", "CEG", "DFA", "EGB", "FAC", "GBD"}: | |
print("Yes") | |
else: | |
print("No") |
B - TaK Code
上から
- 左上の縦
マス, 横 マスの領域は全て黒である. - 右下の縦
マス, 横 マスの領域は全て黒である. - 左上に接する
マスの領域は全て白である. - 左右下に接する
マスの領域は全て白である.
def TaK_code_check(grid, offset_i, offset_j): | |
"""以下がTaK Codeの条件を満たすかを返す | |
上からoffset_i行目、左からoffset_j列目を左上とする縦9マス横9マスの領域 | |
Args: | |
grid (list[list[bool]]): 調査対象を含む領域 | |
offset_i (int): 左上の座標i | |
offset_j (int): 左上の座標j | |
Returns: | |
bool: 調査結果 TrueならばTaK Codeの条件を満たす | |
""" | |
# 左上の縦3マス、横3マスの領域は全て黒である | |
for ii in range(3): | |
for jj in range(3): | |
if not grid[offset_i + ii][offset_j + jj]: | |
return False | |
# 右下の縦3マス、横3マスの領域は全て黒である | |
for ii in range(6, 9): | |
for jj in range(6, 9): | |
if not grid[offset_i + ii][offset_j + jj]: | |
return False | |
# 左上に接する7マスの領域は全て白である | |
for jj in range(3): | |
if grid[offset_i + 3][offset_j + jj]: | |
return False | |
for ii in range(3): | |
if grid[offset_i + ii][offset_j + 3]: | |
return False | |
# 右下に接する7マスの領域は全て白である | |
for jj in range(5, 9): | |
if grid[offset_i + 5][offset_j + jj]: | |
return False | |
for ii in range(5, 9): | |
if grid[offset_i + ii][offset_j + 5]: | |
return False | |
return True | |
# 入力 | |
N, M = map(int, input().split()) | |
S = [[s == "#" for s in list(input())] for _ in range(N)] | |
# 出力 | |
for i in range(N - 8): | |
for j in range(M - 8): | |
if TaK_code_check(S, i, j): | |
print(i + 1, j + 1) |
C - Invisible Hand
「
「
import bisect | |
def count_seller(selling_price_list, price): | |
"""price円で売ってもよいと考える売り手の人数を返す | |
Args: | |
selling_price_list (list[int]): ある売り手が売ってもよいと考える値段のリスト(昇順ソート済み) | |
price (int): 金額 | |
Returns: | |
int: 人数 | |
""" | |
return bisect.bisect_right(selling_price_list, price) | |
def count_buyer(buying_price_list, price): | |
"""price円で買ってもよいと考える買い手の人数を返す | |
Args: | |
selling_price_list (list[int]): ある買い手が買ってもよいと考える値段のリスト(昇順ソート済み) | |
price (int): 金額 | |
Returns: | |
int: 人数 | |
""" | |
return len(buying_price_list) - bisect.bisect_left(buying_price_list, price) | |
# 入力 | |
N, M = map(int, input().split()) | |
A = list(map(int, input().split())) | |
B = list(map(int, input().split())) | |
A.sort() | |
B.sort() | |
# 二分探索をして、問題の金額を求める | |
low = 0 | |
high = 10000000000 | |
while high - low > 1: | |
mid = low + (high - low) // 2 | |
if count_seller(A, mid) >= count_buyer(B, mid): | |
high = mid | |
else: | |
low = mid | |
# 出力 | |
print(high) |
D - Count Bracket Sequences
解説より, 文字列
- 任意の
について, の 文字目までに含まれる(
の個数は)
の個数以上である. に含まれる(
の個数と)
の個数は等しい.
例えば, 入力例1に関係する括弧列として紹介されている()()()
と(())()
は, 上記2つの条件を満たします.
そこで, 以下のような2次元配列を用いた動的計画法(dynamic programming)を考えます.
: 文字目までにある?
を(
あるいは)
に置き換える方法の数. ただし, 以下を満たす方法である.- 任意の
に対し, 文字目までに含まれる(
の個数が)
の個数以上である. - (
文字までの(
の個数) ( 文字までの)
の個数) となる.
- 任意の
初期条件として,
(
の場合:(
の数が増えるので…… +=
)
の場合:)
の数が増えるので…… +=
?
の場合:(
の数が増える場合と)
の数が増えるの両方を考慮して…… += +=
最終的に
この方法だと, CPython 3.11.4だとTLEですが, PyPy 3.10-v7.3.12だとACです.
# 入力 | |
S = list(input()) | |
N = len(S) | |
MOD = 998244353 | |
# dp_ij:i文字目までにある?を(あるいは)に置き換える方法 | |
# ・任意のk <= iに対し、k文字目までに含まれる(の個数が)の個数以上である | |
# ・(i文字までの ( の個数)−(i文字までの ) の個数)=jとなる | |
dp = [[0 for _ in range(N + 1)] for _ in range(N + 1)] | |
dp[0][0] = 1 | |
# dpを計算して埋めていく | |
for i in range(N): | |
if S[i] == "(": | |
for j in range(N - 1): | |
dp[i + 1][j + 1] += dp[i][j] | |
elif S[i] == ")": | |
for j in range(1, N): | |
dp[i + 1][j - 1] += dp[i][j] | |
else: | |
for j in range(N - 1): | |
dp[i + 1][j + 1] += dp[i][j] | |
for j in range(1, N): | |
dp[i + 1][j - 1] += dp[i][j] | |
# 出力 | |
print(dp[N][0] % MOD) |
E以降
E以降は私の能力不足故に省略いたします.
参考にしたサイト等
- 「解説 - ユニークビジョンプログラミングコンテスト2023 夏 (AtCoder Beginner Contest 312)」
Editorial - UNIQUE VISION Programming Contest 2023 Summer(AtCoder Beginner Contest 312)
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)