AtCoder Beginner Contest 124感想戦

コンテストやったきりで復習しないマンなので,
blogに書くことによって強制的に復習するライフハック()を実践していく.

ABC 124

atcoder.jp

A - Buttons

https://atcoder.jp/contests/abc124/tasks/abc124_a

解けた.

A, B = map(int, input().split())
max_num = max([A, B])
if(abs(A-B) >= 1):
print(max_num*2 - 1)
else:
print(max_num*2)

解説見てたら max(A*2-1, B*2-1, A*B) みたいな感じがコメントで流れてきて,それも良いなぁと思った.

B - Great Ocean View

https://atcoder.jp/contests/abc124/tasks/abc124_b

解けた.

N = int(input())
Hn = list(map(int, input().split()))
count = 0
for num, i in enumerate(Hn[1:]):
    if(max(Hn[:num+1]) <= i):
        count += 1
print(count + 1)

なんか,書いたら解けてた.未だに問題よくわかってない説ある.

C - Coloring Colorfully

https://atcoder.jp/contests/abc124/tasks/abc124_c

解けた.

S = list(map(int, input()))
start0 = [0, 1]*(len(S)//2+1)
start1 = [1, 0]*(len(S)//2+1)
ans = [0, 0]
for i, j, k in zip(S, start0, start1):
    if(i != j):
        ans[0] += 1
    if(i != k):
        ans[1] += 1
print(min(ans))

最初は,

for i, char in S:
    if(i%2 == char):
        count += 1

みたいな感じで書こうかと思ってたんだけど,思考力を奪われたのでlistを用意した.

D - Handstand

https://atcoder.jp/contests/abc124/tasks/abc124_d

解けなかった.....
0の連続した長さ,1の連続した長さの累積和をコネコネして,出来そうなんだけど出来なかった.....

Twitterで「0始まりはウザイので長さ0最初に付け足して,1始まりと同じにした」的なツイートに気づかされた.
終わった後,ゲームしてたけど悔しくてまたチャレンジしてみたら出来た........

import numpy as np
N, K = map(int, input().split())
S = input()
len0 = [len(i) for i in S.split('1') if (len(i)) != 0]
len1 = [len(i) for i in S.split('0') if (len(i)) != 0]

lens = np.zeros(len(len0)+len(len1), dtype=np.int)
if(int(S[0])==0):
    lens[::2] = len0
    lens[1::2] = len1
else:
    lens[::2] = len1
    lens[1::2] = len0
lens = np.cumsum(lens)
    
if(S[0] == "0"):
    lens = np.insert(lens, 0, 0)
lens = np.append(lens, [lens[-1]]*(K*2))

if(K >= len(len0)):
    print(len(S))
else:
    ans = []
    max_num = 0
    for first, i in enumerate(range(K*2, len(lens), 2)):
        if(first == 0):
            ans = lens[i]
        else:
            ans = lens[i] - lens[i-(K*2)-1]
        if(ans > max_num):
            max_num = ans
    
    print(max_num)

う~ん.....
しゃくとり法でやると良い感じに出来るっぽいので,そっちも書けるようにしたい感isある. 後で見てみる.

2019/04/14 (どこかで拾ったD問のしゃくとり法を使ったコード)

n, k = map(int, input().split())
s = input()

s += 'X'

i = 0
j = 0
zero = 1 if s[0] == '0' else 0
ans = 0
while j < n:
    if zero <= k:
        ans = max(ans, j - i + 1)
        if s[j] == '1' and s[j + 1] == '0':
            zero += 1
        j += 1
    else:
        if s[i] == '0' and s[i + 1] == '1':
            zero -= 1
        i += 1

print(ans)

理解のために,途中の変数の動きを表示してみた.
入力は入力例2の

14 2
11101010110011
14 2

11101010110011
 i  j     s      zero ans 
 0  1     1       0    1  
 0  2     11      0    2  
 0  3    111      1    3  
 0  4    1110     1    4  
 0  5   11101     2    5  
 0  6   111010    2    6  
 0  7  1110101    3    7  
 1  7   110101    3    7  
 2  7   10101     3    7  
 3  7    0101     3    7  
 4  7    101      2    7  
 4  8    1010     2    7  
 4  9   10101     2    7  
 4 10   101011    3    7  
 5 10   01011     3    7  
 6 10    1011     2    7  
 6 11   10110     2    7  
 6 12   101100    2    7  
 6 13  1011001    2    7  
 6 14  10110011   2    8  
8

実際に使いこなせるかは置いておいて,何となくはわかった.
アルゴリズムってすごいニャー.....

結果

f:id:goldfish-man:20190414022812p:plain