3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AtCoder Beginner Contest 413 振り返り

Posted at

最近参加できていないですが、ABC413参加したので振り返りです。
今回は1時間遅れのUnratedでした。

結果

今回はABの2完でした。
Unratedなので順位の変動はなしです。

ふりかえり

A問題

配列の合計がm以下であることを判定すれば良いです。

main :: IO ()
main = do
  [_, m] <- getInts
  as <- getInts

  printYn $ sum as <= m

B問題

リスト内包表記を使って全ての組み合わせを抽出し、nubOrdで重複を排除してカウントしました。

main :: IO ()
main = do
  n <- readLn @Int
  ss <- replicateM n getLine

  print $ (length . nubOrd) [(ss !! i) ++ (ss !! j) | let idx = [0 .. n - 1], i <- idx, j <- idx, i /= j]

C問題

Data.Sequenceをキューとして使い、クエリ毎に処理していくことで解きます。
ただ、pushする時の繰り返しの数cの範囲が1≤c≤10^9, popする時の個数kが1≤k≤min(10^9 ,n)となっているため、律儀にpushやpopをするとTLEになってしまいます。

そのため、ある値とその繰り返しの数を(繰り返しの数, 値)のようなタプルにしてpushするようにします。

このような方法はランレングス圧縮1と呼ばれています。

本番ではランレングス圧縮が必要なことに気づかずTLEで終わってしまいました。

main :: IO ()
main = do
  q <- readLn @Int
  qs <- replicateM q getInts
  let seq = Seq.empty
  foldM_
    ( \seq q -> case q of
        [1, c, x] -> return $ seq :|> (c, x)
        [2, k] -> do
          let (remaining, total) = removeK k seq 0
          print total
          return remaining
        _ -> error "invalid query pattern"
    )
    seq
    qs

removeK 0 seq acc = (seq, acc)
removeK k seq acc =
  case seq of
    Seq.Empty -> (seq, acc)
    (count, val) :<| rest
      | k >= count -> removeK (k - count) rest (acc + count * val)
      | otherwise -> ((count - k, val) :<| rest, acc + k * val)

全体を振り返って

最近忙しくて中々参加できないのですが、そろそろ復帰したいです。

  1. https://ja.wikipedia.org/wiki/%E9%80%A3%E9%95%B7%E5%9C%A7%E7%B8%AE

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?