LoginSignup
1
0

More than 1 year has passed since last update.

PythonでAtCoder Beginners Selection 解答と感想

Last updated at Posted at 2021-08-01

プログラミングを勉強してみようと思ったけど、普通にやっても続く気がしないのでゲーム感覚で競技プログラミングをやってみようと思った。
https://atcoder.jp/contests/abs

Welcome to AtCoder

題名からして最初の一問
input()で入力を受け取って、int()で数値に変換して、+で足して、print()で出力するくらいかな。

A = int(input())
BC = input()
S = input()

B,C = BC.split( )

print(str(A+int(B)+int(C))+" " + S)

Product

Welcome to AtCoderよりも簡単そう
算術演算子の+%、if文が使えれば特に難しいことはないかな
ここでmap()を覚えてコードがより短くなった


A,B = map(int,input().split())

if (A*B % 2) == 0:
    print("Even")
else:
    print("Odd")

Placing Marbles

発想としては1が書かれたマスにビー玉を置くんだから出てくる数字を全部足せば良いと思った。
なので文字列を文字ごとに分割する方法を検索したらlist()が出てきた。
listっていうクラスがあって、それの型コンストラクタを使うと文字ごとに分割されるらしい。
クラスとか型コンストラクタとかに関してはまだよくわかっていないから後で詳しくやりたい。

A,B,C = map(int,list(input()))

print(A+B+C)

Shift only

全ての要素についてtrueかどうかを判定したいと思って調べたらall()any()が出てきた。
map()を覚えて使いまくってる。ジェネレータ式というものがあるらしく、覚えたらそっちの方が簡単に書けそう。

input()
A = list(map(int,input().split()))

def half(n):
    return n/2
def evenJudge(n):
    return n % 2 == 0 

i = 0

while True:
    if all(list(map(evenJudge,A))):
        A = list(map(half,A))
        i = i + 1
    else:
        break

print(i)

Coins

多重ループができれば解けるっていう問題かな。
別の場所で似たような問題を解いたことがあるけど、拡張性を考えて再起関数を使ったような記憶。
競技プログラミングでは実行速度が大事だけど、システムを作る時には拡張性や可読性を考えて作らないといけないため、どういうプログラムを書くかは考えて学んでいかないといけないと思った。

A = int(input())
B = int(input())
C = int(input())
X = int(input())

n=0
for i in range(A+1):
    for j in range(B+1):
        for k in range(C+1):
            if i * 500 + j * 100 + k * 50 == X:
                n = n+1

print(n)

Some Sums

条件に沿えば足していくだけかなと
条件をどう判定するか、各桁の足し算をどう行うかが肝なのかな?
(もう少し綺麗に書けたらと思うんですけど何かありますかね)

N,A,B = map(int,input().split())

num = 0

for i in range(N+1):
    if A<= sum(map(int,list(str(i)))) <= B:
        num = num + i

print(num)

Card Game for Two

.sort()で大きい順に並べて、偶数番目を足して奇数番目を引く(0番目から数えて)。
if文とループを使ったけどスライスっていうものがあって偶数番目だけを取り出すのはA[::2]、奇数番目だけを取り出すのはA[1::2]とすれば良いらしい。
見たことある気はするけどよくわからなかったからスルーしてた。実際に使う場面は結構ありそうだから覚えておかねば。

N = int(input())
A = list(map(int,input().split()))

A.sort()

point = 0

for i in range(N):
    m = A.pop()

    if i % 2 == 0:
        point +=  m
    else:
        point -=  m

print(point)

Kagami Mochi

ソートして0番目から順番に値が大きくなっていたらカウントっていう風にした。
set()という型コンストラクタを使えば重複がないデータの集合ができるらしく、len(set(D))で良いらしい。

N = int(input())

D = []

for i in range(N):
    d = int(input())
    D.append(d)

D.sort()
n = 1
for i in range(N-1):
    if D[i] < D[i+1]:
        n = n + 1

print(n)

Otoshidama

i,jが決まるとkが一意になるのに気づかずにWAを出しまくった。
ある程度のことはプログラムがやってくれるからと思って処理を短くする努力を全然していなかったかな。
あと、return()以外の上手いやりかたが思いつかずに関数を定義してしまったけど、普通にexit()を使えばよかった。
知識として聞いたことはあっても身についてないことが多いかなぁ。

N,Y = map(int,input().split())

def check(N,Y):
    for i in reversed(range(N+1)):
        for j in reversed(range(N+1-i)):
            k = N-i-j
            if i * 10000 + j * 5000 + k * 1000 == Y:
                return(str(i) + " " + str(j) + " " + str(k))

    return('-1 -1 -1')
print(check(N,Y))

白昼夢

前から一致している文字列を消していけば良いかと思ったが、dreamerとdreameraseの見分けがつかなくて前からだと厳しそう。後ろからやっていけば良いのではと考える。
結果ゴリ押し感が否めない拡張性皆無の見にくいソースが出来上がってしまった。
調べてみると指定文字列で終了するか調べる.endswith()というものがあったため、それを使えばもう少し見た目の良いソースができそう。

S  = input()

while len(S) != 0:
    if S[-5:] == "dream" or S[-5:] == "erase":
        S = S[:-5]
    elif S[-6:] == "eraser":
        S = S[:-6]
    elif S[-7:] == "dreamer":
        S = S[:-7]
    else:
        print("NO")
        exit()

print("YES")

書き直し

下のように書き直してみた。最初は.removesuffix()を使おうとしたんだけどREが出てしまった。
この辺り原因すらよくわかってないからその辺の知識もつけていかないといけないなぁと。

S  = input()

while len(S) != 0:
    for removeS in ["erase","dream","eraser","dreamer"]:
        if S.endswith(removeS):
            S = S[:-len(removeS)]
            break
    else:
        print("NO")
        exit()

print("YES")

Traveling

距離的に届くかどうかと毎秒動き続けるのでちょうどよく止まれるかどうかの2条件を確認すれば良いかなと。
同じループを2回書いてしまっているし、全部配列に入れなくても処理できるので、前の地点だけ保存しておいて、受け取ってすぐに処理するようにすればよかったと思った。

N = int(input())
TXY = [[0,0,0]]
for i in range(N):
    TXY.append(list(map(int,input().split())))

for i in range(N):
    if abs(TXY[i+1][2]-TXY[i][2]) + abs(TXY[i+1][1]-TXY[i][1]) <= TXY[i+1][0] - TXY[i][0]\
        and (abs(TXY[i+1][2]-TXY[i][2]) + abs(TXY[i+1][1]-TXY[i][1]))%2 == (TXY[i+1][0] - TXY[i][0]) % 2:
        continue
    else:
        print("No")
        exit()
print("Yes")

まとめ

プログラミング言語の知識不足で色々調べなきゃいけないことは多かったが、Beginners Selectionというだけあって根本の考え方がどうしてもわからないと言ったことはなかった。
プログラム自体はそんなに時間かからずにかけたけど記事を書くのにだいぶ時間がかかってしまったなぁという感想。
記事を書く際に概念が全然理解できてないから調べて書くっていうことが多かった。(大したことは書いてないけれども)
あとは単純に日本語力がないかな・・・・
記事の書き方も書いていく上で向上していけたらなぁって感じですね。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0