xsd #4861(2007/12/17 16:39 GMT) [ OCaml ] Rating1/1=1.00
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
let magic n = let m mask a = mask lor (1 lsl (a-1)) in let rec loop n r c mask acc = if c = 0 || r > (n*c-(n*(n-1)/2)) then acc else ( if n = 1 then ( if r <= c then (m mask r) :: acc else acc ) else ( let x = r - c in let acc = if x > 0 then loop (n-1) x (min (c-1) x) (m mask c) acc else acc in loop n r (c-1) mask acc ) ) in let rec filter mask acc = function | [] -> acc | hd :: tl -> filter mask (if (hd land mask) <> 0 then acc else hd :: acc) tl in let rec search n mask acc = function | [] -> acc | hd :: tl -> if (mask land hd) <> 0 then let tl = if n > 1 then filter mask [] tl else tl in search n mask acc tl else ( if n = 1 then acc + 1 else ( let acc = search (n-1) (mask lor hd) acc tl in search n mask acc tl ) ) in search n 0 0 (loop n (n*(n*n+1)/2) (n*n) 0 []) let _ = Printf.printf "%d\n" (magic (int_of_string Sys.argv.(1)))
Rating1/1=1.00-0+
[ reply ]
xsd
#4861()
[
OCaml
]
Rating1/1=1.00
私の用意した方法も#4835 minkeさんと同じ戦略で、ビットマスクを使うことを想定していました。
(ビットマスクを使っていない#4833 kozimaさんの方法が意外に速くて驚きました。)
それ以外は特に凝ったことはしていませんが、OCamlの再帰とmallocのコストが低いおかげで、2秒くらいで答えが出ました。
[xsd@celldev dk108]$ time ./dk108 5
3245664
real 0m2.056s
user 0m2.054s
sys 0m0.002s
Rating1/1=1.00-0+
[ reply ]