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
什么?你问我剩下的题?先咕了(其实是我不会)