まえおき
勉強の為にやっているので、ググったり時には解説読みながらやっております。
ご了承ください。
A問題:Happy Birthday!
問題文からして、AとBが共に8以下である必要がある。
a,b = map(int,input().split())
if (a <= 8) and (b <= 8):
print('Yay!')
else:
print(':(')
B問題:Ringo's Favorite Numbers
Nを100^D倍するだけだな!
D,N = map(int,input().split())
print(N*(100**D))
当然のようにWAした。
N = 100
の時に割れる回数が一回増えてしまうので、条件を満たさなくなってしまうことを見落としていた。
本当は一般化した方が良いのだろうけど、今回は問題の制約がN ≦ 100
なので
D,N = map(int,input().split())
if N == 100: N += 1
print(N*(100**D))
これでよかろう。
C問題:*3 or /2
少し考えて、3倍は気にする必要がなく、何回2で割れるかを数えるだけと気づいた。
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)
もっと良い書き方あるかなー。
他の方の回答を見てみる
似てるやつ
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()
も必要なくね?
全然違うやつ
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問題はまだまだ手が付けられそうにないので、解説と解答例を見ていくことにする。
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([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)]
こんなリストを生成しているようです。
#標準入力
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文で同じインデックスの要素を掛けて足してtmp
にappend()
して降順ソートしてm個足す。
sum(tmp[:m])
はとてもオシャレでいいですね。
ans = max(ans, x)
も便利そうです。
if ans < x:ans = x
みたいなことせずに済みそう。
やはり他人のコード読むのが一番勉強になる。
P○izaは課金しないと模範解答見れないのでやはりAtCoderが良いのかな。