AtCoder Beginner Contest 326 振り返り

恒例の振り返りです。

結果

今回はBまでしか解けませんでした。。

各問題の振り返り

A - 2UP3DOWN

ちょっとハマってしまいました…

main :: IO ()
main = do
  (x, y) <- readPairInt
  if (y > x) && (y - x <= 2) || (x > y) && (x - y <= 3) then putStrLn "Yes" else putStrLn "No"

B - 326-like Numbers

これは特に問題なく解けました。divModが商と余りを同時に得られて便利。

main :: IO ()
main = do
  n <- readInputInt
  let listOf326Numbers = generate326Numbers
  print $ minimum $ V.filter (>= n) listOf326Numbers

isLike326Number :: Int -> Bool
isLike326Number n =
  let (hundreds, rest) = n `divMod` 100
      (tens, ones) = rest `divMod` 10
   in hundreds * tens == ones

C - Peak(Upsolved)

今回残念ながら解けませんでした。尺取法と呼ばれる方法を使って解くのがセオリーなようです。
Haskellの尺取法はhttps://zenn.dev/osushi0x/articles/e5bd9fe60abee4が参考になりました。

main :: IO ()
main = do
  (n, m) <- readPairInt
  positions <- readInputIntList
  print $ solve n m (VU.fromList $ L.sort positions)

solve :: Int -> Int -> VU.Vector Int -> Int
solve n m positions = shakutori 0 0 0 positions
  where
    shakutori :: Int -> Int -> Int -> VU.Vector Int -> Int
    shakutori left right maxCount positions
      | right >= n = maxCount
      | otherwise =
          let start = positions VU.! left
              end = positions VU.! right
           in if end - start < m
                then shakutori left (right + 1) (max maxCount (right - left + 1)) positions
                else shakutori (left + 1) right maxCount positions

ちなみに二分探索でも解けます。

main :: IO ()
main = do
  (n, m) <- readPairInt
  positions <- readInputIntList
  let sortedPositions = V.fromList $ L.sort positions
  print $ countPresents m sortedPositions n

countPresents :: Int -> V.Vector Int -> Int -> Int
countPresents m positions n =
  let findMaxPresents startPos =
        let endPos = upperBinarySearch (startPos + 1) (n - 1) (positions V.! startPos + m)
         in endPos - startPos
      upperBinarySearch low high x
        | low > high = low
        | otherwise =
            let mid = (low + high) `div` 2
             in if positions V.! mid < x
                  then upperBinarySearch (mid + 1) high x
                  else upperBinarySearch low (mid - 1) x
   in maximum $ map findMaxPresents [0 .. n - 1]

全体を振り返って

今回全然だめだった。。実力不足なので練習します!

この記事が気に入ったらサポートをしてみませんか?