AtCoder Beginner Contest 159 / Python


f:id:penyooo:20200112235130p:plain


  • 初学者です。( 2019 / 9 ~ 現在7ヵ月目 )
  • AtCoder の問題に Python で取り組んでいます。
  • ABC で4問目(茶か緑)まで解けることを目標にしています。

完全に独学なのでコードは酷いと思います。

AtCoder やってる方、お気軽にコメントください。





結果


f:id:penyooo:20200322230713p:plain

今回は問題の雰囲気が少し違ったような。
気のせいかな?気のせいか



そろそろホントにレーティングが苦しくなってきた。

みんなが解ける問題だけ解いて上げるのはもう限界を感じる。

とは言え5問目、6問目が解けるかと言われると・・・

まだ早押しクイズ方式で頑張った方が可能性を感じる。



問題と解答と勉強


atcoder.jp



提出したコード
import math
 
def combinations_count(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
 
N, M = map(int, input().split())
n = 0
m = 0
 
if N >= 2:
    n = combinations_count(N, 2)
if M >= 2:
    m = combinations_count(M, 2)
 
print(n + m)


何か血迷った。

未だに緊張するんよね、早く解かなきゃ!って。

1問目からコンビネーションなんて使う訳ないやんね。

2個組み合わせるだけなら使う必要ないよねぇぇぇ。

何考えてたんだろうか。

修正版
N, M = map(int, input().split())

print(int(N * (N - 1) / 2 +  M * (M - 1) / 2))









atcoder.jp



提出したコード
def pal(s): return 0 if s==s[::-1] else 1

S = input()


if pal(S) + pal(S[:int((len(S)-1)/2)]) + pal(S[int((len(S)+3)/2)-1:]) == 0:
    print("Yes")
else:
    print("No")


これはこれで良いはず。

ちなみに実はこれはちょっとカッコつけて書き直している。

def pal(s):
    h = int(len(s)/2)
    for a, b in zip(s[:h], reversed(s[-h:])):
        if a != b: return 1
    return 0


本当に提出したやつは回文の関数こう書いていた。

どっちでも良いような気がするんだけど、
計算速度は上の方が全然早いらしいからやっぱり上で書きたい。

豆知識:回文は英語で palindrome









atcoder.jp

提出したコード
from decimal import Decimal
 
print((Decimal(input()) / 3) ** 3)


これ正直何が狙いの問題かわからなかった。

どこに引っ掛かる要素があるのか疑いまくって、
小数の計算がズレるやつだろ!確信!と思って Decimal を使ってみたのだが。

print((int(input()) / 3) ** 3)


なんと、普通に計算しただけのやつ通るのよね。

絶対に引っ掛けだと思って提出前にめっちゃ考えた時間を返して欲しい。

3問目こんなことあるん??何か出題ミスかな??

誤差の許容範囲をもっと狭める予定だったとか??








atcoder.jp



提出したコード
import math
import collections

def cmb(n, r):
    return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
    
N = int(input())
M = input().split()

total = 0
count = collections.Counter(M)

for i in count.values():
    if i >= 2:
        total += cmb(i, 2)
    
for j in M:
    print(total - (count[j]-1))


これは個人的に結構キレイに書けたと思っているやつ。

1問目と同じでコンビネーション要らんかったけどね。



collections.Counter() で何の数字が何個あるか数えて。

それぞれの数字の組み合わせ数を求めて合計しておく。

最後出力するときに、自分を含めた組み合わせの数を引く。



どうすかね?どうすかね。

最近 Counter() を覚えたので使えて嬉しいやつ。










atcoder.jp



珍しく5問目にしては何がしたい問題なのか非常にわかりやすい問題。

だ・が・し・か・し。

解き方がわかるかどうかは別問題。

んー、無念。



方法的には全通り検索で良かったみたい。

めっちゃ丁寧に書いて下さっているので勉強させて頂きます。
import itertools
 
H, W, K = map(int, input().split())
S = []
for _ in range(H):
    S.append([int(s) for s in input()])
# print(S)
 
ans = 2000
for t in itertools.product([0, 1], repeat=H - 1):
    # print("t:",t,"横ライン")
    cnt = t.count(1)
    lst = [[s for s in S[0]]]
    for h in range(H - 1):
        if t[h]: # 切るとき
            lst.append(S[h + 1])
        else: # 切らないとき
            lst[-1] = [lst[-1][i] + S[h + 1][i] for i in range(W)] #縦成分を足す
    L = len(lst)
    # print("lst:",lst)
    # print(cnt,L)
    sum_lst = [0] * L
    for w in range(W):
        # print([lst[i][w] for i in range(L)])
        if max(lst[i][w] for i in range(L)) > K:
            # print("break")
            break
        tmp = [sum_lst[i] + lst[i][w] for i in range(L)]
        # print("w=",w,tmp)
        if max(tmp) > K:
            cnt += 1
            # print("切る!!")
            sum_lst = [lst[i][w] for i in range(L)]
            # print(sum_lst)
        else:
            sum_lst = tmp
    else: # for文がすべて回り切ったら、発動
        ans = min(ans, cnt)
print(ans)
"""
for t in itertools.product([0, 1], repeat=H - 1):
    print(t)
"""



余裕あるんだろうなぁカッコいい。

時間内にこのレベルのコードを書けるようになりたいもんだわい。








atcoder.jp

6問目は安定の問題文がそもそも何言ってるかわからないやつ。









愚痴:

前回さ、見たよ、だけで良いからコメントちょうだいって書いたじゃん。

0件よねコメント。

いいよいいよ、誰も見てないんでしょうよ。

自分の復習の為に書いてるだけだから別に良いもんねーーだ。ふーーん。