あるぱかのブログ

AtCoder茶(レート578)

AtCoder Beginner Contest 349

A - Zero Sum Game

リンク:A - Zero Sum Game (atcoder.jp)

概要: N-1人の勝ち点をみて N人目の勝ち点を計算してね

2人が戦って勝てば勝ち点1、負ければ勝ち点-1になるので、全員の勝ち点の総和を取ると必ず0になります(問題のタイトル通りです)。

そのため N-1人の勝ち点総和を計算して、0から引く(もしくは-1を掛ける)ことで N人目の勝ち点が分かります。

#ABC349 A - Zero Sum Game
N = int(input())
A = list(map(int, input().split()))
ans = -sum(A)
print(ans)  

提出リンク:提出 #52295867 - AtCoder Beginner Contest 349

B - Commencement

リンク:B - Commencement (atcoder.jp)

概要:文字列 Sに登場する英小文字の数が以下の条件を満たすか判定してね

 S にちょうど  i 回現れる文字はちょうど 0 種類またはちょうど2 種類ある

言い回しが難しいですが、各英小文字が文字列 Sに登場する回数を数えて度数分布を作成、さらに度数分布に登場する数の度数分布を作って0と2以外があればNG、という方針で押し通せそうです。

以下のコードでは文字の度数分布を n、登場回数の度数分布を numとしています。

(以下のコードでは nの作成にCounter、 numの作成にdefaultdictを使用していますが、 numについてもCounter(num)で同じことができるので本来はCounterだけで済みます)

例えば入力例1:commencementに対して n numは以下のようになります。

n = Counter({'m': 3, 'e': 3, 'c': 2, 'n': 2, 'o': 1, 't': 1})
num = defaultdict(int, {2: 2, 1: 2, 3: 2})

 numを見るとたしかに1回登場する文字が2種類(o,t)、2回登場する文字が2種類(c,n)、3回登場する文字が2種類(m,e)あることが分かります。

#ABC349 B - Commencement
from collections import Counter
from collections import defaultdict
S = input()
n = Counter(S)
num = defaultdict(int)
for key in n:
    num[n[key]] += 1
ans = 'Yes'
for key in num:
    if num[key] != 2:
        ans = 'No'
print(ans)  

提出リンク:提出 #52305590 - AtCoder Beginner Contest 349

C - Airport Code

リンク:C - Airport Code (atcoder.jp)

概要:文字列 Tを小文字に直したときに文字列 Sの部分文字列(連続でなくてOK)であるか判定してね

 Tは3文字で確定なので1文字目を持って Sを走査していき、一致する文字があれば1文字目はクリア、2文字目について同様に・・・という流れでいけそうです。

 |S| \leq 10^{5}ということですが二重ループを使う場面は無いので特に気にする必要は無いです。

部分文字列ということなのでおそらく S=abcdefに対して T=FDAみたいな取り方はNGなんだろうと思います。

#ABC349 C - Airport Code
S = input()
T = input()
T = T.lower()
flag_1 = False
flag_2 = False
flag_3 = False
l1 = 0
l2 = 0
for i in range(len(S)):
    if S[i] == T[0]:
        flag_1 = True
        l1 = i
        break
for i in range(l1+1, len(S)):
    if S[i] == T[1]:
        flag_2 = True
        l2 = i
        break
if T[2] == 'x':
    flag_3 = True
else:
    for i in range(l2+1, len(S)):
        if S[i] == T[2]:
            flag_3 = True
ans = 'No'
if flag_1:
    if flag_2:
        if flag_3:
            ans = 'Yes'
print(ans)  

提出リンク:提出 #52317824 - AtCoder Beginner Contest 349

D - Divide Interval

なにがなにやらさっぱり・・・

E - Weighted Tic-Tac-Toe

リンク:E - Weighted Tic-Tac-Toe (atcoder.jp)

概要:配点付き三目並べをして勝利するプレイヤーを教えてね

今回はD、E両方とも450点でした。

こちらは実装が重そうなもののやるべきことは明確そうに思います。

お気持ちとしては

1ターン目高橋君は盤面の得点最大を取る

 複数あれば盤面中央を優先的にとる

2ターン目以降は以下の優先度で行動する

 自分のビンゴ完成

 相手のリーチつぶし

 得点最大をとる

 得点最大が負の値ならリーチを作りに行く

 (取得済のマスから縦、横(、斜め)を見て相手がいない列かつ得点最大のマスをとる)
 ターン終了時にビンゴチェック、完成していたらゲーム終了
 ビンゴなしでゲーム終了したときは得点の総和で勝負

になるんですが1時間ではちょっとしんどいですね・・・と思い椅子温めタイム終了としました。

後日じっくり時間かけて実装だけはしてみようと思います。

結果

いつも通りA~Cの3完21分で4386位でした。

D問題よりE問題のほうが正答率低いんですね。

レート更新されたら追記します。