ICPC2005 Regional, Tokyo の問題Bを Haskell で.queue を使ったシミュレーションだけど面倒だから一ターンごとにリスト生成...
-- Problem B in ACM/ICPC 2005 ASIA Regional Tokyo
-- 2005/11/04 Brute Force
import Control.Monad
import Debug.Trace
main = getProblems >>= mapM_ (putStrLn.show.solve)
getProblems =
do
[m, c, n] <- getNums
if (n==0 && m==0 && c==0) then return []
else do
xs <- replicateM n getEntry
liftM ((m,c,n,xs):) getProblems
where
getEntry = getNums >> getNums
getNums = liftM (map read.words) getLine
-- it's better to make each entry of ds the pair of it and its length
solve (m,c,n,xs) = sl xs 0 (take m $ repeat [])
where
sl [] t _ = t
sl ys t ds = let
(hs, ys') = unzip $ map (\x->(head x, tail x)) ys
(t', ds') = sl' ds hs
in sl (filter (not.(==[])) ys') (t'+t) ds'
sl' ds = foldl searchOne (0,ds)
searchOne (t, ds) x = let
p = length $ takeWhile (not.or.map (==x)) ds
ds' =if p<m then take p ds++[filter (not.(==x)) (ds!!p)]++drop (p+1) ds
else ds
in insertOne (t+p+1) ds' x
insertOne t ds x =
if length (head ds) < c then (t+1, (x:head ds):tail ds)
else let
p = length $ takeWhile ((==c).length) ds
ds' = if p<m then take p ds++[x:(ds!!p)]++drop (p+1) ds
else ds
p' = length $ takeWhile ((==c).length) ds'
hds = head ds
tds = tail ds
q = p'-1
tds' =if p'<m then take q tds++[last hds:(tds!!q)]++drop (q+1) tds
else tds
in (t+p+p'+p+5, (x:init hds):tds')
- Newer: ことはじめ