LoginSignup
0
3

More than 5 years have passed since last update.

AtCoderの過去問をPythonで解く(解けるとは言っていない)#ABC100

Posted at

まえおき

勉強の為にやっているので、ググったり時には解説読みながらやっております。
ご了承ください。

A問題:Happy Birthday!

問題文からして、AとBが共に8以下である必要がある。

Birthday.py
a,b = map(int,input().split())
if (a <= 8) and (b <= 8):
    print('Yay!')
else:
    print(':(')

B問題:Ringo's Favorite Numbers

Nを100^D倍するだけだな!

Numbers.py
D,N = map(int,input().split())
print(N*(100**D))

当然のようにWAした。
N = 100 の時に割れる回数が一回増えてしまうので、条件を満たさなくなってしまうことを見落としていた。
本当は一般化した方が良いのだろうけど、今回は問題の制約がN ≦ 100なので

Numbers2.py
D,N = map(int,input().split())
if N == 100: N += 1
print(N*(100**D))

これでよかろう。

C問題:*3 or /2

少し考えて、3倍は気にする必要がなく、何回2で割れるかを数えるだけと気づいた。

/2.py
num = int(input())
lis = list(map(int,input().split()))

ans = 0
for i in range(num):
    while lis[i]%2 == 0:
        lis[i] = lis[i]/2
        ans += 1
print(ans)

もっと良い書き方あるかなー。

他の方の回答を見てみる

似てるやつ

/2'.py
num = int(input())
lis = map(int,input().split())

ans = 0
for number in lis:
    while number%2 == 0:
        number /= 2
        ans += 1

・一旦リストにしてインデックスでアクセスするより直接イテレータとして使ったほうが良い。
・なのでmapオブジェクトをlist()する必要もない。
・あれ?最初のinput()も必要なくね?

全然違うやつ

/2''.py
input();print(sum(bin(i)[::-1].index('1') for i in map(int,input().split())))

ワンライナーで書けるのかー。
内包表記がとてもPythonっぽい。
初見だと意味がわからなかったので調べてみた。

input();で標準入力の1行目をスキップしている。
map(int,input().split())の部分がイテレータ。
sum()の引数が内包表記になっている。
bin(i)[::-1]で要素を2進数にして逆順にしている。
.index('1')で何文字目に1が最初に出てくるか=何回2で割れるか。

とても勉強になりますね。
ビット演算はそこそこ頻出らしいので押さえておきたい。

D問題:Patisserie ABC

うーん、わからん。方針すらわからん。
D問題はまだまだ手が付けられそうにないので、解説と解答例を見ていくことにする。

Patisserie.py
from itertools import product
n,m = map(int,input().split())
cake = [list(map(int,input().split())) for i in range(n)]

ans = 0
for x,y,z in product([1,-1], repeat = 3):
    tmp = []
    for a,b,c in cake:
        tmp.append(a * x + b * y + c * z)
    tmp.sort(reverse= True)
    ans = max(ans,sum(tmp[:m]))
print(ans)

他にもっと早いのも短いのもあるけども、可読性はこれが一番な気がした。

itertools.product()でデカルト積を生成
 詳しい説明はここを参考にしました。

product
product([1,-1], repeat = 3)
<itertools.product at 0x1ffc0b60708>

list(product([1,-1], repeat = 3))
[( 1,  1,  1),
 ( 1,  1, -1),
 ( 1, -1,  1),
 ( 1, -1, -1),
 (-1,  1,  1),
 (-1,  1, -1),
 (-1, -1,  1),
 (-1, -1, -1)]

こんなリストを生成しているようです。

cake
#標準入力
5 3
1 -2 3
-4 5 -6
7 -8 -9
-10 11 -12
13 -14 15

n,m = map(int,input().split())
cake = [list(map(int,input().split())) for i in range(n)]
print(cake)
[[1, -2, 3],
 [-4, 5, -6],
 [7, -8, 9],
 [-10, 11, -12],
 [13, -14, 15]]

こちらでは各ケーキのプロパティを二次元配列にしている。
これらを掛け合わせて8通りの全探索をする。
2重for文で同じインデックスの要素を掛けて足してtmpappend()して降順ソートしてm個足す。

sum(tmp[:m])はとてもオシャレでいいですね。
ans = max(ans, x)も便利そうです。
if ans < x:ans = xみたいなことせずに済みそう。

やはり他人のコード読むのが一番勉強になる。
P○izaは課金しないと模範解答見れないのでやはりAtCoderが良いのかな。

0
3
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
0
3