渡り鳥の旅路

元半導体系エンジニア、今Webエンジニアの雑記

AtCoder ABC 151 C - Welcome to AtCoder (300 点)

はじめてのABC

問題へのリンク

問題概要

AtCoderを受けている状況を想定

  • N問のの問題に対してM回の回答を行う。
  • i番目の提出はp_i番目の問題への提出で、結果はS_i('AC' or 'WA')である。
  • 提出結果を元に正答数とペナルティ数を求める。
    • 正答数の条件:'AC'を1回以上出した問題の数
    • ペナルティ数の条件:'AC'を1回以上出した各問題において、初めて'AC'を出すまでに出した'WA'の数の総和

制約

  • N, M, p_iは整数
  • 1<= N <= 105
  • 0<= M <= 105
  • 1<= p_i <= N
  • S_iは'AC'または'WA'

解法(本番でやった)

問題数決まってるし最初にN個分の容れ物用意するか?でも全部解くわけでもないし、バケット(Rubyだとハッシュ)にp_iをキーとした値を適宜入れていこう、という方針で進めた。

2段階の処理を、数え上げの条件に注意しながら実装した。

  1. バケットにデータを入れる。
  2. バケットを利用して数え上げ

ペナルティの数え方と、2回目以降の'AC'が出るケースはやり過ごすあたりに注意が必要。

n, m = gets.split.map(&:to_i)

scores = {}
penas = {}

m.times do
  inputs = gets.split
  p = inputs[0].to_i
  s = inputs[1]

  if s == 'AC'
    if scores[p] != 'AC'
      scores[p] = 'AC'
    end
  else # WA
    if scores[p] != 'AC'
      if penas[p].nil?
        penas[p] = 1
      else
        penas[p] += 1
      end
    end
  end
end

score_count = 0
pena_count = 0

scores.each do |k,v|
  if v == 'AC'
    score_count += 1
    pena_count += penas[k] unless penas[k].nil?
  end 
end

puts "#{score_count} #{pena_count}"

解答例は最初からバケットにN個分の要素を用意するやり方をしてた。