Codeforces 146B - B. Lucky Mask
整数 a, b が与えられたとき、c のマスクが b と等しく、かつ c > a であるような c を求めよという問題。
「c のマスクが b と等しい」とは、整数 c から 4 と 7 以外の数字を取り除いた数が b と等しいという意味。
制約:
1 <= a, b <= 10^5
全探索。
mask :: Int -> Int mask n | null s = 0 | otherwise = read s where s = filter (\c -> c == '4' || c == '7') $ show n calc :: Int -> Int -> Int calc a b = head [i | i <- [a+1..], b == mask i] main = do s <- getLine let [a, b] = map read $ words s :: [Int] print $ calc a b
はじめにmask関数を書いたとき、if式を用いていたけど、ガードに書き直した。ガードの方が読みやすく分かりやすい。
mask :: Int -> Int mask n = if null s then 0 else read s where s = filter (\c -> c == '4' || c == '7') $ show n
Codeforces 221A - A. Little Elephant and Function
221A - A. Little Elephant and Function
calc :: Int -> [Int] calc 1 = [1] calc 2 = [2, 1] calc n = [n, 1] ++ [2..n-1] main = do s <- getLine putStrLn $ unwords $ map show $ calc $ read s
Codeforces 26A - A. Almost Prime
素因数分解したときに、素因数の種類が 2 つかどうか求める問題。
import Data.List factorize :: Int -> [Int] factorize 1 = [1] factorize n = fac 2 n where fac p n | n == 1 = [] | n `mod` p == 0 = p : fac p (n `div` p) | otherwise = fac (p+1) n isAlmostPrime :: Int -> Bool isAlmostPrime n = 2 == (length $ nub $ factorize n) calc :: Int -> Int calc n = sum [1 | i <- [1..n], isAlmostPrime i] main = do s <- getLine print $ calc $ read s
リストの中にpredを満たすものがいくつあるか個数を返す関数が標準ライブラリにありそうだと思って調べたけれど見つかりませんでした。
Codeforces 148A - A. Insomnia cure
calc :: Int -> Int -> Int -> Int -> Int -> Int calc k l m n d = d - length [i | i <- [1..d], i `mod` k /= 0, i `mod` l /= 0, i `mod` m /= 0, i `mod` n /= 0] main = do s <- getContents let [k, l, m, n, d] = map read $ lines s :: [Int] print $ calc k l m n d
英文の読み方
英文が難しいけど、意味が分からないところは読み飛ばして最後まで読んでみる。それからまたはじめに戻って全体を読み返す。それを何度か繰り返すと、なんとなく意味がつかめてくる箇所が出てくる(分からないままのことも多いけど)。それから入力と出力のサンプルも確認する。入出力は問題文の意味を読み解くヒントになることも少なくない。
Codeforces 3A - A. Shortest path of the king
3A - A. Shortest path of the king
import Data.Char parse :: String -> (Int, Int) parse s = (digitToInt (s!!1), ord (s!!0) - ord 'a' + 1) calc :: (Int, Int) -> (Int, Int) -> [String] calc (sr, sc) (dr, dc) | sr == dr && sc == dc = [] | otherwise = dir : calc (r, c) (dr, dc) where r = sr + signum (dr - sr) c = sc + signum (dc - sc) dir = (move sc dc "R" "L") ++ (move sr dr "U" "D") move src dst lt gt | src == dst = "" | src < dst = lt | otherwise = gt main :: IO () main = do s <- getLine t <- getLine let moves = calc (parse s) (parse t) print $ length moves mapM_ putStrLn moves
mapM_ はまだよく意味が分かっていない。
参考:
Codeforces 139A - A. Petr and Book
calc :: Int -> [Int] -> Int calc n pages = calc' n (cycle pages) (cycle [1..7]) where calc' n (p:pages) (d:dayWeek) | n <= p = d | otherwise = calc' (n-p) pages dayWeek main = do s <- getLine t <- getLine print $ calc (read s) (map read $ words t)
Codeforces 146A - A. Lucky Ticket
import Data.Char isLucky :: String -> Bool isLucky s = all (\c -> c == '4' || c == '7') s calc :: String -> String calc s = if isLucky s && sum hd == sum tl then "YES" else "NO" where xs = map digitToInt s n = length s `div` 2 hd = take n xs tl = drop n xs main = do s <- getLine t <- getLine putStrLn $ calc t