haskell代码,仅修改了处理数据输入就通过了,(*^▽^*)
查看原帖
haskell代码,仅修改了处理数据输入就通过了,(*^▽^*)
625398
_OTZ_楼主2024/10/3 23:02

一开始感觉仅有输入不同,所以试了试仅修改处理输入数据的函数,没想到直接通过了,开心!! (*^▽^*)

第一次使用 Monad Transformer, 劳烦大佬们看看是否正确, 谢谢Thanks♪(・ω・)ノ


相较于 P1006题解 - haskell初学者,求大佬指教写法思路 仅修改了 getAllWeightedPoint 函数及其调用

module Main where

import Control.Monad.Reader (MonadReader (ask), ReaderT (runReaderT), liftIO)
import Control.Monad.State (MonadState (get), State, evalState, modify)
import qualified Data.Map as M
import Data.Maybe (fromMaybe)

main :: IO ()
main = do
  [m, n] <- fmap read . words <$> getLine
  weightedPoints <- runReaderT getAllWeightedPoint m
  putStrLn
    . show
    . flip evalState mempty
    . flip runReaderT (weightedPoints, (m, n))
    $ (dfs (1, 0) (1, 0))

type Point = (Int, Int)

type WeightedPoints = M.Map Point Int {- Weight -}

getAllWeightedPoint :: ReaderT Int {- lengthOfRow -} IO WeightedPoints
getAllWeightedPoint =
  M.fromList <$> getAllLines 1
  where
    getAllLines lineNum = do
      lengthOfRow <- ask
      if lineNum > lengthOfRow
        then return []
        else do
          matrixRow <- fmap read . words <$> liftIO getLine
          (zip (zip (repeat lineNum) [(1 :: Int) ..]) matrixRow ++) <$> getAllLines (lineNum + 1)

type Cache = M.Map (Point, Point) Int

dfs :: Point -> Point -> (ReaderT (WeightedPoints, Point) (State Cache) Int)
dfs pfst@(xfst, yfst) psnd@(xsnd, ysnd) = do
  cache <- get
  (weightedPoints, targetPoint) <- ask
  case M.lookup (pfst, psnd) cache of
    Just v -> return v
    Nothing -> do
      dd <- nextStep (xfst + 1, yfst) (xsnd + 1, ysnd)
      dr <- nextStep (xfst + 1, yfst) (xsnd, ysnd + 1)
      rd <- nextStep (xfst, yfst + 1) (xsnd + 1, ysnd)
      rr <- nextStep (xfst, yfst + 1) (xsnd, ysnd + 1)
      let max' = maximum [dd, dr, rd, rr]
      modify $ M.insert (pfst, psnd) max'
      return max'
      where
        nextStep pnfst pnsnd =
          if isPointInBounds pnfst targetPoint && isPointInBounds pnsnd targetPoint
            then (addWeight pnfst) . (if (pnfst /= pnsnd) then (addWeight pnsnd) else id) <$> dfs pnfst pnsnd
            else return $ 0
        addWeight p = (+) . fromMaybe 0 $ M.lookup p weightedPoints

isPointInBounds :: Point -> Point -> Bool
isPointInBounds (x, y) (bx, by) = x > 0 && x <= bx && y > 0 && y <= by
2024/10/3 23:02
加载中...