AtCoder Regular Contest B - せんべい

問題概要

リンク

  • 1 ~ Nまでの数字が書かれたせんべいがランダムな順番で与えられる
  • シカは1枚目から順にせんべいを食べるか、食べないか選ぶ
  • シカは全部でK枚のせんべいを食べられる
  • シカはn枚目のせんべいを見ている時, 1 ~ n枚目のせんべいの大小関係がわかる
  • シカはNの数字が書かれたせんべいを食べられるよう最適な選択を取る
  • シカがNの数字が書かれたせんべいを食べられる確率を求める

解法

動的計画法
dp[n][k]:=n番目のせんべいを見ている時、まだNを食べていないとする。あとk枚食べられる時、Nを食べられる確率。
メモ化再帰で計算する。
dp[0][K]が答え。

AtCoder Regular Contest 55 C - ABCAC

問題概要

リンク

文字列Sに対して
S=A+B+C+A+C
となるような部分文字列A, B, Cがいくつ考えうる数え上げる。

解法

部分点

  • AとCの文字数を決める
  • O(N2)
  • 条件を満たすかはローリングハッシュでO(1)

満点

  • SをABCとACに分ける境目を探索する
  • その際、Z algorithmを使ってAとして考えうる文字列で最長のもの、Cとして考えうる文字列で最長のものを求める
  • 上記の値から、境目で分けた場合に考えうるA, B, Cの数を計算する

参考

AtCoder ARC #055 : C - ABCAC

Aim Tech Div2 C. Graph and String

本番中は,UnionFindのコードをコピペして座ってるだけ.
本番後,Twitterで参加者のツイートを見てAC.


問題はこちら

問題概要

  • a,b,cから構成される文字列に対応したグラフを考える
    • 文字列のi番目の文字はi番目のノードに対応している
    • 文字列のi番目の文字とj番目の文字が同じであればノードi, jは必ず隣接する
    • i番目の文字とj番目の文字がアルファベット順で隣同士であれば隣接する
      • すなわち,aとb,bとcは隣接する
      • aとcは隣接しない
  • グラフが与えられるので以上の条件を満たす文字列があるかを考える
  • 無い場合は“No”,ある場合は“Yes”と候補として考えられる文字列を一つ出力する

解法

  • 全てのノードからbの候補となるもの見つける
    • bは全てのノードと隣接している
    • すなわちbから出る辺はn-1本
  • bの候補とそのエッジを取り除いたグラフから強連結成分を見つける
    • 色々あるけど張ってあったのでUnionFindを使った
  • 検出した強連結成分はaとcの候補
    • 3つ以上強連結成分があればNoを出力
  • 検出した強連結成分は完全グラフでなければならない
    • bの候補に向かって張ってる辺を除いた辺の数が強連結成分のノード数-1となる
    • なっていなければNoを出力
  • ここまででNoが出力されていなければYes
    • b候補のノードをb,強連結成分に属するノードをaかc (異なる強連結成分同士で異なればどちらでもよい) として出力

Suffix Array

新しいアルゴリズムを学んだので自分用の備忘録.

Suffix Arrayとは

  • 日本語では接尾辞配列
  • ある文字列の全ての接尾辞を辞書順に並べたもの
  • 例えば “coder” という文字列について考える
    接尾辞は “coder”, “oder”, “der” “er”, “r”, “”
    接尾辞配列は以下の通り
開始位置 接尾辞
5
0 coder
2 der
3 er
1 oder
4 r

Suffix Arrayの構築

  • 愚直に構築することを考える
  • その他の方法
  • 今回はManber&Myersについて学ぶことにする

Manber&Myers

  • 接尾辞配列の最初の1文字でソート→2文字でソート→4文字でソート…
  • すでにソート済みの情報を使うので1回のソートは[latex]\mathcal{O}(n\log{n})[/latex]
  • よって[latex]\mathcal{O}(n \log^2 n)[/latex]
  • 蟻本の説明とコードを見ても理解に時間かかったのでコードにコメントをつけた

CodeforcesでACした問題を確認できるサイトを作った

CodeforcesでACした問題を確認できるサイトを作った.

CodeforcesACList

Codeforces AC List

使い方

フォームにCodeforcesのIDを入れてEnterを押すだけ.
ACした問題は緑色になる.

作った経緯

競技プログラミングの能力を効率的にあげるには,自分に適したレベルの問題を解くことが重要だと考えている.
自分にとっては,Div. 2 C 〜 D辺りが (問題が読めれば) 解けるか解けないかのボーダーラインなので,それを簡単に確認したい.
また,新しい問題の方がネット上での解説が充実しているので,新しい問題から順番に解いていきたい.
そこでコンテスト名 (Div. 1かDiv. 2かそれ以外かを知りたいため) と,そのコンテストの自分の解答状況が,最新のものから順番に確認できる仕組みが必要となった.

実装

CodeforcesAPIを提供している.
http://codeforces.com/api/contest.list?gym=falseにアクセスすれば,コンテストのリストがJSON形式で得られる.
http://codeforces.com/api/user.status?handle=user_idにアクセスすれば,user_idの提出状況がJSONで形式得られる.
これをPHPから叩いて適当に実装した.

お願い

もし何かバグっていたら@tkw_techまで連絡して頂けるとありがたいです. ちなみに,6問以上あるコンテストもE問題までしか表示してないのは仕様です.
そのうち (Codeforces Round #hoge以外を解きたくなった時?),直すかもしれません.

Typical DP Contest C. トーナメント

※このエントリは競プロで圧倒的成長 Advent Calendar 2015の25日目のエントリです.

問題

問題概要

  • トーナメントを行う
  • 参加者iのレートはRiである
  • レートRpとレートRqが戦った時,前者が勝つ確率は
    [latex]\frac{1}{1+10^{(Rq-Rp)/400}}[/latex]
  • 各参加者が優勝する確率を求める

解法

プログラムを追いながらの方がわかりやすいのでコメントに記述した.k回戦で戦う可能性が誰であるかを求めるのが味噌.

Typical DP Contest A. コンテスト

※このエントリは競プロで圧倒的成長 Advent Calendar 2015の24日目のエントリです.

問題

問題概要

  • N問のコンテストがある
  • i問目の点数はpiである
  • このコンテストで獲得できる得点のパターンは何種類か

解法

  • dp[i][j]:=i問目までj点を獲得できるか (できる: 1, できない: 0) とする
  • dp[0][0]=1
  • dp[i][j-p[i]]ならdp[i+1][j]=1である

※本当は配列を使いまわせばdp[2][10001]の配列で解ける.が,メモリに余裕があるのでそうしなかった.