1
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?

HaskellでABC442を解く

Posted at

はじめに

久しぶりに4問解けましたが解くスピードが遅くて順位はあんまり上がらなかった。

A問題

iかjの文字のみ集計してカウントする。

A問題提出

main = do
  s <- getLine
  let ans = filter (\c -> c =='i' || c == 'j') s
  print $ length ans

B問題

音量とON/OFFの状態を管理する。

B問題提出

main = do
  q <- readLn :: IO Int
  as <- replicateM q readLn
  putStr $ unlines $ map (bool "No" "Yes") $ solve as

solve = step False (0::Int)
  where
    step _playing _vol [] = []
    step playing vol (a:as)
      | a == 1 = f (playing,vol+1) : step playing (vol+1) as
      | a == 2 = let vol1 = if vol > 0 then (vol-1) else 0 in f (playing,vol1) : step playing vol1 as
      | otherwise = let playing1 = not playing in f (playing1,vol) : step playing1 vol as
    f (playing,vol) = playing && vol >= 3

C問題

著者と繋がっている利害関係者の数を管理する。
それ以外の人が査読者としてふさわしいのでその組み合わせを答える。

C問題提出

main = do
  [n,m] <- readInts
  abs <- fmap concat <$> replicateM m $ do
    [a,b] <- readInts
    return [(a,1),(b,1)]
  let g1 = A.accumArray (+) 0 (1,n) abs :: AU.Array Int Int
  putStrLn $ unwords $ map show $ solve g1

solve g = map step [1..n]
  where
    (_,n) = AU.bounds g
    step i = c2 $ n - g A.! i - 1

c2 i
  | i <= 2 = 0
  | otherwise = i * (i-1) * (i-2) `div` 6

D問題

数列の値をゴリゴリ書き換えていく。
また隣がスワップした場合累積和の値が局所的に変更になるので
それも都度書き換えれば良い。
やることは単純だったが配列の値を直接書き換えるようなコードはどうしても長くなってしまい
型エラーでなかなか実装がうまく行かずコード書くのに時間がかかってしまう。

D問題提出

main = do
  [n,q] <- readInts
  as <- readInts
  let arrA = AU.listArray (1,n) as :: AU.UArray Int Int
  let arrS = AU.listArray (0,n) $ scanl (+) 0 as :: AU.UArray Int Int
  qs <- replicateM q readInts
  let cands = solve arrA arrS qs
  let ans = filter (/=(-1)) cands
  putStr $ unlines $ map show ans

solve arrA arrS qs = runST $ do
  arrAA <- AM.thaw arrA :: ST s (STUArray s Int Int)
  arrSS <- AM.thaw arrS :: ST s (STUArray s Int Int)
  forM qs $ \q -> do
    case q of
      (1:x:_) -> do
        -- swap
        val1 <- AM.readArray arrAA x
        val2 <- AM.readArray arrAA (x+1)
        AM.writeArray arrAA x val2
        AM.writeArray arrAA (x+1) val1

        -- scanl
        val3 <- AM.readArray arrSS x
        AM.writeArray arrSS x (val3+val2-val1)
        return (-1)
        
      (2:l:r:_) -> do
        val4 <- AM.readArray arrSS r
        val3 <- AM.readArray arrSS (l-1)
        return (val4-val3)
      _ -> error "error"

おわりに

久しぶりの4問回答はやっぱり嬉しい!

1
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
1
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?