TopCoder SRM 440 Div1 Medium in F#
F#で書いた。工夫した点?知りませんなぁ。
let maze = ["........."; "XXX.XXXX."; ".XX.X...."; ".....XX.X"] let sx, sy = 0, 0 let dx, dy = [1; -1; 0; 0], [0; 0; 1; -1] let N, M = List.length maze, maze.[0].Length let ex = Array2.init N M (fun _ _ -> 0.0) let rec dfs1 x y px py = let l = [for i in 0..3 -> let nx = x + dx.[i] let ny = y + dy.[i] if (nx <> px || ny <> py) && nx >= 0 && ny >= 0 && nx < M && ny < N && maze.[ny].[nx] <> 'X' then dfs1 nx ny x y; ex.[ny, nx] + 1.0 else 0.0] in ex.[y, x] <- 1.0 + List.fold_left (+) 0.0 l let exsum = ref 0.0 let rec dfs2 x y px py sum = let nsum = sum + ex.[y, x] exsum := !exsum + nsum; [for i in 0..3 -> let nx = x + dx.[i] let ny = y + dy.[i] if (nx <> px || ny <> py) && nx >= 0 && ny >= 0 && nx < M && ny < N && maze.[ny].[nx] <> 'X' then dfs2 nx ny x y nsum] |> ignore let rec count s c n = match s with | [] -> n | x::xs -> if x = c then count xs c (n + 1) else count xs c n let expectedTime () = dfs1 sx sy -1 -1; dfs2 sx sy -1 -1 -ex.[sy, sx]; let ct = List.fold_left (+) 0 [for i in 0..N-1 -> count [for c in maze.[i] -> c] '.' 0] in !exsum / float ct
実行結果↓
> expectedTime ();; val it : float = 167.2608696