O(1)のリスト(配列)アクセス
IOUArrayを使うとO(1)での要素アクセスが実現できるそうです
IOモナド環境に限定されてしまいますが、どうせ対話式でIOモナドのなかで動作しているので都合は悪くなさそうです。
実装
リスト版とほとんど同じですね
gcj.hs
import Control.Monad
import System.IO
import Data.Array.IO
type IOField = IOUArray (Int,Int) Int
solve :: Int -> IOField -> Int -> IO ()
solve a f n = do
putStrLn $ shows n " 2"
(x:y:_) <- (map read.words) <$> getLine
writeArray f (x,y) 1
s<-(\a b c->a+b+c)<$>readArray f (n-1,1)<*>readArray f (n-1,2)<*>readArray f (n-1,3)
case s of
3 | n < a -> solve a f $ n+1
3 | n == a -> s2 $ n+1
otherwise -> solve a f n
s2 n = do
putStrLn $ shows n " 2"
(x:y:_) <- (map read.words) <$> getLine
case (x,y) of
(0,0) -> return ()
(_,_) -> s2 n
main = do
hSetBuffering stdout NoBuffering
t <- readLn
replicateM_ t $ do
a <- readLn
area <- newArray ((1,1), (67,3)) 0 :: IO IOField
solve ((a+2) `div` 3 -2) area 2
type宣言
型:IOUArray (Int,Int) Intはいかにも長いので別名を宣言しておきます。
O(1)でアクセスできるので普通に2次元配列にしています