• 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
    

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

  • 相关阅读:
    LaTeX入门
    用jdom来解析xml文件小Demo
    Java乔晓松基于注解的面向AOP(切面)编程
    三层架构实战篇—系统登录实例
    selenium ide插件介绍
    WPF17行为(以控件在界面拖动为例)
    火狐浏览器显示“已阻止载入混合活动内容“的解决方法
    博客园—打赏功能
    网页返回顶部的几种方法
    自定义美化博客园
  • 原文地址:https://www.cnblogs.com/shanxieng/p/13967246.html
Copyright © 2020-2023  润新知