AtCoder Beginner Contest 271 レポート
摘要
ABC3完と大敗を喫しました.先月初めて入水したのも束の間,早速緑に出戻りです
敗因としては,
- C:漠然とした方針を複数思いつき悩んでしまった
- D:方針からDPの漸化式までスムーズに思いつくも範囲外参照に気付けず
というところです.
ABC271
- コンテスト名: 京セラプログラミングコンテスト2022(AtCoder Beginner Contest 271)
- 順位: 2958th / 8491
- パフォーマンス: 840
- レーティング: 1202 → 1171 (-31)
- コンテスト参加回数: 58
A - 484558
A - 問題
0以上255以下の整数
A - 解法
「hex()
とかformat()
とか使えばいいんだろう」と思いつつ,調べるほどでもないと思い愚直に計算してAC.
A - ACコード
def main():
N = int(input())
s = '0123456789ABCDEF'
ans = s[N//16]+s[N%16]
print(ans)
if __name__ == '__main__': main()
A - 改良版
N = int(input())
ans = '{:02X}'.format(N)
print(ans)
B - Maintain Multiple Sequences
B - 問題
与えられた
B - 解法
素直に実装してAC.
B - ACコード
def main():
N, Q = map(int, input().split())
arr = [[0]] + [list(map(int, input().split())) for _ in range(N)]
for _ in range(Q):
s, t = map(int, input().split())
print(arr[s][t])
if __name__ == '__main__': main()
C - Manga
C - 問題
与えられた長さ
C - 解法
とりあえず重複する要素についてはそれぞれ1つを残して売り飛ばす弾にしておく.
その上で,1から
ここで,最初から思い付いていた答え決め打ち二分探索を素直に実装すればよかったのに,
「1から愚直にシミュレーションを回しても計算量的に間に合うのでは,またその方が実装が楽なのでは」
と無駄に悩み時間を大きく無駄にしてしまう.
最終的に二分探索で実装するも,探索範囲の上限が
C - ACコード
from collections import Counter
from bisect import bisect_right
def main():
global N, A
N = int(input())
A = list(map(int, input().split()))
ans = solve()
print(ans)
def solve():
cnt = Counter(A)
rem = sum(v-1 for v in cnt.values())
arr = sorted(set(A))
leng = len(arr)
ok, ng = 0, N+1
while abs(ng-ok) > 1:
md = (ok+ng)//2
idx = bisect_right(arr, md)
if 2*(md - idx) <= leng - idx + rem: ok = md
else: ng = md
return ok
if __name__ == '__main__': main()
C - WAコード
ok, ng = 0, N
while abs(ng-ok) > 1: ## 探索がN-1で止まってしまう
md = (ok+ng)//2
D - Flip and Adjust
D - 問題
2個の整数
D - 解法
ぱっと見ナップサック問題.
和が最小値
配るDPで漸化式を立て,可能かどうかの判定だけでなく解の復元についても処理を決め,
制約
コンテスト終了10分前で実装ができたと確信するも一部ケースでRE.配列の参照エラーであろうことは見当がついたものの時間内にバグ取りできず終了.
D - ACコード(追試)
def main():
N, S = map(int, input().split())
arr = [list(map(int, input().split())) for _ in range(N)]
ans = solve(N, S, arr)
print(*ans, sep='\n')
def solve(N, S, arr):
cards = [[h > t, abs(h-t)] for h, t in arr]
mn = sum(arr[i][cards[i][0]] for i in range(N))
if mn > S: return ['No']
if mn == S: return make(cards[i][0] for i in range(N))
sm = S-mn
dp = [[False]*(sm+101) for _ in range(N+1)]
dp[0][0] = True
for i in range(N):
for j in range(sm+1):
if dp[i][j]:
dp[i+1][j] = True
dp[i+1][j+cards[i][1]] = True
if not dp[N][sm]: return ['No']
for i in range(N-1, -1, -1):
if not dp[i][sm]:
cards[i][0] = not cards[i][0]
sm -= cards[i][1]
return make(cards[i][0] for i in range(N))
def make(turns): return ['Yes', ''.join('T' if turn else 'H' for turn in turns)]
if __name__ == '__main__': main()
D - WAコード
def solve(N, S, arr):
cards = [[h > t, abs(h-t)] for h, t in arr]
mn = sum(arr[i][cards[i][0]] for i in range(N))
mx = sum(arr[i][1-cards[i][0]] for i in range(N))
if mn > S: return False # ここでmxがSより小さい場合についても除外する必要あり
turns = [turn for turn, _ in cards]
if mn == S: return make(turns)
dp = [[False]*(mx-mn+1) for _ in range(N+1)]
dp[0][0] = True
for i in range(N):
for j in range(mx-mn+1):
if dp[i][j]:
dp[i+1][j] = True
if j+cards[i][0] <= mx-mn: dp[i+1][j+cards[i][1]] = True
if not dp[N][S-mn]: return False # mx < S の場合エラー
感想
デバッグ下手すぎでした.
新しいアルゴリズムやデータ構造を詰め込む以前に,知っているものを正しく使えるように練度をあげていきたいと思います.
Discussion