wvogel日記

自分用の技術備忘録が多めです.

木?全探索?

codeforcesこの問題

どうやったら解けるかな、と考えたときに、円を作るんだから、前から順番に、一番最初に見つかった要素を積んでいっても解けるんじゃないか?
と思った。

main = do
  n <- getLine
  ls <- getLine
  putStrLn $ judge $
    arrange ([head $ list ls],tail $ list ls) 
            (read n, product [1..read n])
  where
    list = map read.words 
    
    judge True = "YES"
    judge False = "NO"

arrange :: ([Int],[Int]) -> (Int,Int) -> Bool
arrange _ (n,-1) = False
arrange (as,[b]) _  = last as `equal1` b
                      && head as `equal1` b
--arrange (as,[]) (n,_) = n==length as
arrange (as,b:bs) (n,k)
  = if head as `equal1` b
      then arrange ((b:as),bs) (n,k-1)
      else arrange (as,bs++[b])  (n,k-1)

equal1 a b = (==1).abs $ a-b

ところがこれじゃうまくいかない。
wrong answerがでたテストデータを見てみると、
やはりいくつかの組み合わせ方があり、そのうちの一つを見つけ出すとなるとこれでは探し出せません。

全探索以外に、木を作って辿っていくとか、
円を形成するということは、
少なくとも同じ値が二つはある、とも考えられる。
そうじゃないと値が上がりっぱなしになってしまうし....
この場合、Haskellではgroup関数が使えないか?


うーん