2
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 477 振り返り

2
Posted at

AtCoder477振り返りです。
最近ずっとさぼってたので久しぶりの出場です

結果

AB2完でした。大怪我です

スクリーンショット 2026-09-27 17.08.59.png

スクリーンショット 2026-09-27 17.08.29.png

ふりかえり

A問題

問題文通りにときました。

main :: IO ()
main = do
  c <- getLine
  putStrLn $ case c of
    "B" -> "Y"
    "Y" -> "R"
    "R" -> "B"
    _ -> error "invalid char: " <> c

B問題

zipWith3を使って前後の差を計算します。
端が漏れるので、そこは別途計算してリストに結合します。

main :: IO ()
main = do
  [n, d] <- getInts
  xs <- sortOn snd . zip [1 ..] <$> getInts
  let z3 = zipWith3 (\(_, a) (i, b) (_, c) -> if b - a >= d && c - b >= d then (i, True) else (i, False)) xs (drop 1 xs) (drop 2 xs)
      xv = V.fromList xs
      h = (fst (xv V.! 0), snd (xv V.! 1) - snd (xv V.! 0) >= d)
      t = (fst (xv V.! (n - 1)), snd (xv V.! (n - 1)) - snd (xv V.! (n - 2)) >= d)
      res = [i | (i, b) <- (h : z3) <> [t], b]
      size = length res
  print size
  printList $ sort res

C問題

クエリごとに部分文字列が含まれるかどうかを計算するとTLEすることは明らかです。そのため計算量を削減する方法を考えます。

事前に部分文字列の含まれる場所を計算して、その開始位置を計算しておくとよさそうです。

そのあとのクエリ処理が問題ですが、ここは累積和を使って出現回数を計算しておき、区間内の値が1以上であることを計算しておけばよいです。(今回はここに気づかずTLEとなりました。)

回答コードは以下の通りです

-- >>> solve "abcdabc" "bc" [(2,6), (3,5), (3,7)]
-- [True,False,True]
solve :: String -> String -> [(Int, Int)] -> [Bool]
solve s t = map q
  where
    q (l, r)
      | r - l + 1 < lenT = False
      | otherwise = (arr IA.! (r - (lenT - 1)) - arr IA.! (l - 1)) > 0
    lenS = length s
    lenT = length t
    arr = g lenS t (f lenT s)

-- >>> f 2 "abcdabc"
-- ["ab","bc","cd","da","ab","bc","c"]
f :: Int -> String -> [String]
f l xs = go xs
  where
    go xs
      | null sb = []
      | otherwise = sb : go (drop 1 xs)
      where
        sb = take l xs

-- >>> g 7 "bc" ["ab","bc","cd","da","ab","bc", "c"]
-- array (0,7) [(0,0),(1,0),(2,1),(3,1),(4,1),(5,1),(6,2),(7,2)]
g :: Int -> String -> [String] -> UArray Int Int
g n t tl = IA.array (0, n) $ zip [0 ..] $ scanl' (+) 0 [bool 0 1 (t == tt) | tt <- tl]

-- Main
main :: IO ()
main = do
  q <- getInt
  s <- getLine
  t <- getLine
  qs <- replicateM q getPairInt
  mapM_ printYn $ solve s t qs

全体を振り返って

久しぶりに出たのですが、やはり頻度を上げた方がいいなーと感じました。
レートが下がるリスクはありますが、さぼらずRatedで参加するようにしたいと思います

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