CSP2020 haskell题解

优秀的拆分

import Data.Char
import Data.Bits

main = do
    n <- readInt
    if n `mod` 2 == 0 then
        solve n 1
    else
        putStr "-1"

solve :: Int -> Int -> IO ()
solve 1 x = putStr (show x)
solve n x = if n `mod` 2 == 1 then do 
                solve (n `div` 2) (x * 2)
                putStr (' ':show x)
            else
                solve (n `div` 2) (x * 2)

readInt :: IO Int
readInt = do
    ch <- getChar
    if isDigit ch then
        f (ord ch - ord '0')
    else if ch == '-' then
        fmap (*(-1)) readInt
    else readInt
    where
        f ans = do
            ch <- getChar
            if isDigit ch then
                f (ans * 10 + ord ch - ord '0')
            else
                return ans

儒略历

好恶心的大模拟,但是用haskell还是简单了一点(并没有)

首先判断是否在1583.10.15日前,然后将时间进到1600.1.1。

往前跳的时候先以400年为周期跳,然后是100年,4年。

import Data.Char

main = do
    n <- readInt
    work n
    return ()

work :: Int -> IO()
work 0 = return ()
work n = do
    x <- readInt
    solve x
    work (n - 1)
    return ()

solve :: Int -> IO()
solve n =
    if n < 2299161 then
        printans (solve1 n)
    else
        printans (solve2 (n - 2299161))

printans :: (Int, Int, Int) -> IO()
printans (d, m, y) = do
    if y > 0 then
        putStrLn (show d ++ ' ' : show m ++ ' ' : show y)
    else
        putStrLn (show d ++ ' ' : show m ++ ' ' : show (1 - y) ++ " BC")

days :: [Int]
days = [31,28,31,30,31,30,31,31,30,31,30,31]

days' :: [Int]
days' = [31,29,31,30,31,30,31,31,30,31,30,31]

solve1 :: Int -> (Int, Int, Int)
solve1 n = let y1 = -4712 + 4 * (n `div` (3 * 365 + 366)) ; x = n `mod` (3 * 365 + 366) in
    fun1 x y1

solve2 :: Int -> (Int, Int, Int)
solve2 n = if n <= 16 then (15 + n, 10, 1582)
    else if n < 47 then (n - 16, 11, 1582)
    else if n < 78 then (n - 46, 12, 1582)
    else let n2 = n - 78 in
        if n2 < 6209 then
            let y1 = 1583 + 4 * (n2 `div` (3 * 365 + 366)) ; n3 = n2 `mod` (3 *365 + 366) in
                if n3 >= 365 then
                    if n3 >= 366 + 365 then
                        if n3 >= 365 * 2 + 366 then getmd days (n3 - 365 - 366 - 365) (y1 + 3) 1
                        else getmd days (n3 - 365 - 366) (y1 + 2) 1
                    else getmd days' (n3 - 365) (y1 + 1) 1
                else getmd days n3 y1 1
        else
            let n4 = (n2 - 6209) `mod` (303 * 365 + 97 * 366) ; y2 = 1600 + 400 * ((n2 - 6209) `div` (303 * 365 + 97 * 366)) in
                if n4 >= (75 * 365 + 25 * 366) then
                    let y3 = y2 + 100 + 100 * ((n4 - 75 * 365 - 25 * 366) `div` (76 * 365 + 24 * 366)) ; n5 = (n4 - 75 * 365 - 25 * 366) `mod` (76 * 365 + 24 * 366) in
                        if n5 >= (365 * 4) then
                            fun2 (n5 - 365 * 4) (y3 + 4)
                        else getmd days (n5 `mod` 365) (y3 + n5 `div` 365) 1
                else
                    fun2 n4 y2

fun1 :: Int -> Int -> (Int, Int, Int)
fun1 x y =
    if x >= 366 then
        let y2 = y + 1 + ((x - 366) `div` 365) ; n = (x - 366) `mod` 365 in
            getmd days n y2 1
    else getmd days' x y 1

fun2 :: Int -> Int -> (Int, Int, Int)
fun2 x y = let y2 = y + 4 * (x `div` (3 * 365 + 366)) ; n = x `mod` (3 * 365 + 366) in
    fun1 n y2

getmd :: [Int] -> Int -> Int -> Int -> (Int, Int, Int)
getmd (d:ds) x y m = if x >= d then getmd ds (x - d) y (m + 1)
    else (x + 1, m, y)

readInt :: IO Int
readInt = do
    ch <- getChar
    if isDigit ch then
        f (ord ch - ord '0')
    else if ch == '-' then
        fmap (*(-1)) readInt
    else readInt
    where
        f ans = do
            ch <- getChar
            if isDigit ch then
                f (ans * 10 + ord ch - ord '0')
            else
                return ans

动物园

我暂时放弃这道题了吧,光读入就超时,我还能怎么办啊。有人知道怎么加快读入吗?

先把我70pts的代码放在这吧

import Data.Char
import Data.Bits

main = do
    n <- readInt
    m <- readInt
    c <- readInt
    k <- readInt
    x1 <- work1 n
    x2 <- work2 m
    putStrLn (show (work3 x1 x2 k - fromIntegral n))
    return ()

work1 :: Int -> IO Int
work1 0 = return 0
work1 n = pure (.|.) <*> readInt <*> work1 (n-1)

work2 :: Int -> IO Int
work2 0 = return 0
work2 n = pure (\x y -> 2 ^ x .|. y) <*> readInt2 <*> work2 (n-1)

readInt2 :: IO Int
readInt2 = do
    x <- readInt
    readInt
    return x

work3 :: Int -> Int -> Int -> Integer
work3 0 0 0 = 1
work3 x y z =
    if y `mod` 2 > x `mod` 2 then work3 (x `div` 2) (y `div` 2) (z - 1)
    else 2 * work3 (x `div` 2) (y `div` 2) (z - 1)

readInt :: IO Int
readInt = do
    ch <- getChar
    if isDigit ch then
        f (ord ch - ord '0')
    else if ch == '-' then
        fmap (*(-1)) readInt
    else readInt
    where
        f ans = do
            ch <- getChar
            if isDigit ch then
                f (ans * 10 + ord ch - ord '0')
            else
                return ans

什么?你问我剩下的题?先咕了(其实是我不会)

posted @ 2020-11-13 00:49  shanxizeng  阅读(154)  评论(0编辑  收藏  举报
广告位招商,有意者请联系