SRM445 550 (練習)
コンテンツ
気分転換に練習問題として,解いてみた.
生成される数列(文字列)が再帰的構造のようなものをもっている.
なので,再帰で書けばシンプル.
アルゴリズムは結構,すぐ思いついた.
しかし,C++は慣れてないので,時間かかったよ.
string password(int n, long long k) { if (n == 1) return k == 1? "0": "1"; long long q = 1 << --n; if (k <= q) return "0" + password(n, k); return "1" + max(pass(n, q), password(n, k - 1 - q)); } string pass(int n, long long k) { if (n == 1) return k == 1 ? "0": "1"; long long q = 1 << --n; if (k <= q) return "0" + pass(n, k); if (k == q + 1) return "1" + pass(n, q); return "1" + pass(n, k - 1 - q); }
教訓
- Stringの比較(辞書式)は <,> 等で可能
- Stringのconcatは + でできる.
- 2 ^ n は 1 << n
- 自分の環境でコンパイルが通っても,相手(TopCoder)の環境でコンパルが通るとは限らない!
しかし,Haskellで書けばもっと,アルゴリズムが見えるのになぁ.
なぜ,TopCoderではHaskellが使えないのか.小一時間,問い詰めたい.
password :: Int -> Integer -> String password 1 1 = "0" password 1 2 = "1" password n k | k <= q = '0' : password (n - 1) k | otherwise = '1' : max (ppart (n - 1) q) (password (n - 1) (k - 1 - q)) where q = 2 ^ (n - 1) ppart :: Int -> Integer -> String ppart 1 1 = "0" ppart 1 2 = "1" ppart n k | k <= q = '0' : ppart (n - 1) k | k == q + 1 = '1' : ppart (n - 1) q | otherwise = '1' : ppart (n - 1) (k - 1 - q) where q = 2 ^ (n - 1)
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)