結果
| 問題 |
No.5002 stick xor
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2018-06-01 20:39:49 |
| 言語 | Haskell (9.10.1) |
| 結果 |
AC
|
| 実行時間 | 891 ms / 1,000 ms |
| コード長 | 2,344 bytes |
| コンパイル時間 | 28,160 ms |
| 実行使用メモリ | 4,868 KB |
| スコア | 37,243 |
| 最終ジャッジ日時 | 2018-06-01 20:40:19 |
|
ジャッジサーバーID (参考情報) |
judge8 / |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 32 |
コンパイルメッセージ
[1 of 1] Compiling Main ( Main.hs, Main.o ) Linking a.out ...
ソースコード
-- Try yukicoder
-- author: Leonardone @ NEETSDKASU
import Data.Char (digitToInt)
import Data.Word (Word64)
import Data.Bits
import Data.List (sortOn)
main = interact $ unlines . map format . solve . parse . lines
parse (nkstr:lsstr:tbstr) = ret where
[n, k] = map read $ words nkstr
ls = zip [0..] . map read $ words lsstr
tb = zip [1..] $ map mf tbstr :: [(Int, Word64)]
ret = (n, k, ls, tb)
mf = fromInteger . foldl f 0
f a b = shiftL a 1 .|. (toInteger $ digitToInt b)
format ((_, l), (y, x)) = unwords $ map show [y, x, y, x + l - 1]
solve (n, k, ls, tb) = ans where
solve' = foldl (fix n) ([], tb)
base = score tb
nosol = map (\e -> (e, (1, 1))) ls
sorted = sortOn snd ls
sol1 = solve' ls
sol2 = solve' $ reverse sorted
sol3 = solve' $ sorted
es = [sol1, sol2, sol3] ++ xs
(ret, _) = foldl cmp (nosol, base) es
ans = sortOn fst ret
cmp o@(sol, sc) (sol', tb') = ret where
sc' = score tb'
ret = if sc < sc' then o else (sol', sc')
xs = map (solve' . snd) . take 5 $ iterate shuffle (19831983, ls)
fullbits n = shiftL 1 n - 1
setbits t x s = t `xor` shiftL x s
getbits x (s, t) = shiftR t s .&. x
find n l t = ret where
fb = fullbits l
mf1 s = (s, setbits t fb s)
mf2 nb = (popCount . getbits fb $ snd nb, nb)
bs = map mf1 [0..n-l]
nbs = zip [n-l+1-i | i <- [0..]] bs
ret = foldl1 f $ map mf2 nbs
f a b = if fst a < fst b then a else b
get tb n l = ret where
ret = foldl1 f $ map mf tb
mf (y, t) = (y, find n l t)
f a b = if fst (snd a) < fst (snd b) then a else b
fix n (r, tb) li@(_, l) = ret where
(y, (_, (x, (_, b)))) = get tb n l
ret = ((li,(y, x)):r, swap b (y-1) tb)
swap u 0 ((i, _):es) = (i, u) : es
swap u p (e:es) = e : swap u (p-1) es
xorshift a = d :: Word64 where
b = a `xor` shiftL a 13
c = b `xor` shiftR b 7
d = c `xor` shiftL c 17
shuffle (xsft, ls) = shake len xsft ls where
len = fromInteger . toInteger $ length ls
tohead 0 (x:xs) f = x : f xs
tohead p (x:xs) f = tohead (p-1) xs (\es -> f $ x:es)
shake 0 x es = (x, es)
shake n x es = shake (n-1) x2 es2 where
x2 = xorshift x
p = x `mod` len
es2 = tohead p es id
score tb = sc where
sc = foldl1 (+) $ map (popCount . snd) tb