tmori’s blog

公開メモ帳くらいの感覚で書いています。技術系多め。日常少なめ。

Atcoder Beginner Contest 157 振り返り 【Python】

はじめに

AtCoder Beginner Contest 157の振り返りをします。

atcoder.jp

A - Duplex Printing

普通にround(N/2)で余裕やんとか思ってたら、round(5/2)が2で少し焦った。 最後の桁数が5の場合、正確に表せないようです。 (詳細: 15. 浮動小数点演算、その問題と制限 — Python 3.8.2 ドキュメント) 時間が経ちすぎて忘れてました。

提出したプログラム

N=int(input())
print(round((N+0.5)/2))

後々見ると汚いので書き直し。

書き直すならこんな感じ

N=int(input())
print((N+1)//2)

B - Bingo

ビンゴの判定をもっとうまいことできればいいなあーと思いつつ、時間の集う上無理やり解きました。 他の人の回答見た感じ、割とみんなゴリ押しで安心しました。

提出したプログラム

card=[list(map(int,input().split())) for i in range(3)]
N=int(input())
target_list=[int(input()) for i in range(N)]
 
for i, line in enumerate(card):
    for j, pt in enumerate(line):
        if pt in target_list:
            card[i][j] = 1 # マークあり
        else:
            card[i][j] = 0 #マークなし
 
result = False
# 横
for l in card:
    if l.count(1) == 3:
        result = True
 
# 縦
for l in list(zip(*card)):
    if l.count(1) == 3:
        result = True
 
# 斜め
if card[1][1] == 1: #真ん中にマークあり
    if card[0][0] == 1 and card[2][2] == 1:
        result = True
    if card[0][2] == 1 and card[2][0] == 1:
        result = True
 
if result:
    print("Yes")
else:
    print("No")

C - Guess The Number

["0"]*NでN桁の最小値を作成して、M個の条件に矛盾がないか確認する。先頭が0の場合に注意すれば、特に問題はなさそう。

提出したプログラム

N,M=map(int,input().split())
sc_list=[list(map(int,input().split())) for i in range(M)]

result_n = [0] * N

flag_lsit = [False] * N

for line in sc_list:
    first_n = line[0]
    second_n = line[1]

    if flag_lsit[first_n-1] == False:
        result_n[first_n-1] = second_n
        flag_lsit[first_n-1] = True
    else:
        if not(result_n[first_n-1] == second_n):
            print(-1)
            exit()
            
# 先頭が0
if result_n[0] == 0:
    if N == 1:
        print(0)
        exit()
    if flag_lsit[0] == True: # 変更があった
        print(-1)
    else:
        result_n[0] = 1
        for i in result_n:
            print(i,end="")
        print()

else:
    for i in result_n:
        print(i,end="")
    print()

AtCoder公式の解説のように、0以上10^N未満の整数をすべて調べる方がコード長を減らせそうですね。

上の解法を使った他の人のプログラム

import sys
N,M=map(int,input().split())
sc=[list(map(int,input().split())) for i in range(M)]
 
for i in range(10**N):
    if len(str(i))<N:
        continue
    lst=list(str(i))
    for s,c in sc:
        if int(lst[s-1])==c:
            continue
        else:
            break
    else:
        print(i)
        sys.exit()
print(-1)

計算量を適切に判断できる力が欲しいです...

終わりに(余談)

大学の卒業研究に追われていて2ヶ月ほどAtCoderを触れていませんでした。
そのせいか大分コーディング力が落ちたように思えます。
もっと頑張らなければ...