図表とざっくりとした解説はこちらからどうぞ。
https://img.atcoder.jp/abc100/editorial.pdf
A. Happy Birthday!
図をよーく見れば、1人が9切れ以上取ることができないことが分かります。
隣接しない = 最低でも1つ間隔を開けなければならない
ということは、8切れ取った時1つ間隔で取ることになりこれが最大です。
全部で16個から8個ずつ取っても問題ないので、全体のケーキの残りについては考える必要がなく、1人最大8切れを守れば良いことになります。
(マイナスの入力は条件から存在しません)
よって、A, B が8以下であることが Yay!
の条件ですので、
1 2 3 4
| if A <= 8 and B <= 8: print("Yay!") else: print(":(")
|
となるように設計すれば良いことになります。
Accepted Code [A. Happy Birthday!]:
1 2 3 4 5 6 7 8 9
| input_line = input().split()
cake_a = int(input_line[0]) cake_b = int(input_line[1])
if cake_a > 8 or cake_b > 8: print(":(") else: print("Yay!")
|
B. Ringo’s Favorite Numbers
色々な解法がありますが、ここでは D = 0 or 1 or 2
ということを利用して解きます(場合分け)
D == 0
“100でちょうど0回割り切れる” == “100で割り切れない”
と考えると解けるかと思います。
コードにすると
1 2
| if number % 100 != 0: do
|
ということですね。
ここで N < 100 であれば単純に答えが N で終わりなのですが、
N <= 100
なので N == 100
について分ける必要があります。
愚直に N == 100
を場合分けしても良いですし、
100の倍数について無視してカウントするようにしても良いです(今回はこちらを採用)
D == 1
“100でちょうど1回割り切れる” == “100で割り切れて、10000で割り切れない”
よってD == 0 の時と同様に N == 100 についてのみ場合分けをするか、
10000の倍数を無視してカウントするようにすれば良いです(今回はこちらを採用)
D == 2
“100でちょうど2回割り切れる” == “10000で割り切れて、1000000で割り切れない”
よってD == 0, 1 の時と同様に N == 100 についてのみ場合分けをするか、
1000000の倍数を無視してカウントするようにすれば良いです(今回はこちらを採用)
Accepted Code [B. Ringo’s Favorite Numbers]:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| input_line = input().split() num_divide = int(input_line[0]) smallest_of = int(input_line[1])
if num_divide == 0: counter = 0 current_num = 0 while counter < smallest_of: current_num += 1 if current_num % 100 == 0: continue else: counter += 1
elif num_divide == 1: counter = 0 current_num = 0 while counter < smallest_of: current_num += 100 if current_num % 10000 != 0 and current_num % 1000000 != 0: counter += 1
else: counter = 0 current_num = 0 while counter < smallest_of: current_num += 10000 if current_num % 1000000 != 0: counter += 1
print(str(current_num))
|
C. *3 or /2
“3倍する” or “2で割り切る” の操作をするのですが、
“3倍する” のはまあ何回でもできますよね。
というわけでネックになるのは “2で割り切る” ことです。
“2で割り切る” 動作は数列に対して 1回の操作で1つ以上適用しなければならないので、
1回の操作で1つを “2で割り切る” と考えます。
するとこの問題は “2で何回割り切れるか” という問題になりますので、
数列のそれぞれの数について “2で何回割り切れるか” を調べます。
いくつか方法はありますが、2進法に変換して0が続く桁数を調べるのが良いでしょう(多分)
Accepted Code [C. *3 or /2]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| array_length = int(input()) input_line = input().split()
array_int = list(map(int, input_line)) array_bin = list(map(bin, array_int)) array_bin_str = list(map(str, array_bin))
array_dividable = []
for i in range(0, array_length): if array_int[i] == 0: array_dividable.append(0) else: target_line = array_bin_str[i] count_dividable = 0 for j in range(1, len(target_line)): target_char = target_line[-j] if target_char == '1': break elif target_char == 'b': break else: count_dividable += 1
array_dividable.append(count_dividable)
if sum(array_dividable) == 0: print("0") else: print(str(sum(array_dividable)))
|
D. Patisserie ABC
全ての場合についてスコアを出そうとすると、ケーキ1000個から500個を取り出すときに計算量が最大で、このとき
C(1000, 500) = 2.702882409E+299
よってこんなんでfor
を回すと帰ってこない(計算が終了しない)ので別の方法を考えます。
ところで、スコアは絶対値を採用するわけですが、
絶対値というのは max(number, -number)
と等価です。
よってこの場合、単純にスコアを足していったあとのことを考えると、
「綺麗さ」「おいしさ」「人気度」の数値が beauty, yummy, popular
だったとして
1 2 3 4 5 6 7 8
| + beauty + yummy + popular + beauty + yummy - popular + beauty - yummy + popular - beauty + yummy + popular - beauty - yummy + popular + beauty - yummy - popular - beauty + yummy - popular - beauty - yummy - popular
|
の8パターンのうち、最大のものが
1
| abs(beauty) + abs(yummy) + abs(popular)
|
と等しいとわかります。
すると、絶対値で考えなくても単純に足していって最後にmax
を出せば良いことがわかります。
さて、ここまできたところでもう一度上の8例について見てみます。
+ beauty - yummy + popular
で考えてみましょう。
これを最大化させるためには + beauty - yummy + popular
を各ケーキに対して算出し、大きいものから順番にケーキの個数だけ取れば良いことに気がつくでしょうか。
すると8パターン全てに対して同じことが言えるのですから、これを計算してmax
を取ればスコアが最大であると言えます。
Accepted Code [D. Patisserie ABC]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| input_line = input().split() total_cake = int(input_line[0]) select_cake = int(input_line[1])
cake_scores = []
for i in range(0, total_cake): input_line = input().split() beauty = int(input_line[0]) yummy = int(input_line[1]) popular = int(input_line[2])
cake_scores.append((beauty, yummy, popular))
scores_p_p_p = [] scores_p_p_n = [] scores_p_n_p = [] scores_n_p_p = [] scores_n_n_p = [] scores_p_n_n = [] scores_n_p_n = [] scores_n_n_n = []
for i in range(0, total_cake): beauty, yummy, popular = cake_scores[i] scores_p_p_p.append(beauty + yummy + popular) scores_p_p_n.append(beauty + yummy - popular) scores_p_n_p.append(beauty - yummy + popular) scores_n_p_p.append(-beauty + yummy + popular) scores_n_n_p.append(-beauty - yummy + popular) scores_p_n_n.append(beauty - yummy - popular) scores_n_p_n.append(-beauty + yummy - popular) scores_n_n_n.append(-beauty - yummy - popular)
scores_p_p_p.sort(reverse=True) scores_p_p_n.sort(reverse=True) scores_p_n_p.sort(reverse=True) scores_n_p_p.sort(reverse=True) scores_n_n_p.sort(reverse=True) scores_p_n_n.sort(reverse=True) scores_n_p_n.sort(reverse=True) scores_n_n_n.sort(reverse=True)
score_p_p_p = sum(scores_p_p_p[0:select_cake]) score_p_p_n = sum(scores_p_p_n[0:select_cake]) score_p_n_p = sum(scores_p_n_p[0:select_cake]) score_n_p_p = sum(scores_n_p_p[0:select_cake]) score_n_n_p = sum(scores_n_n_p[0:select_cake]) score_p_n_n = sum(scores_p_n_n[0:select_cake]) score_n_p_n = sum(scores_n_p_n[0:select_cake]) score_n_n_n = sum(scores_n_n_n[0:select_cake])
print(str(max(score_p_p_p, score_p_p_n, score_p_n_p, score_n_p_p, score_n_n_p, score_p_n_n, score_n_p_n, score_n_n_n)))
|
ABC100 の軌跡
ABC100 の提出記録です。実行時間や使用メモリもわかります
https://beta.atcoder.jp/contests/abc100/submissions?f.Task=&f.Language=&f.Status=&f.User=nuekodory