ABC138 F - Coincidence
解法
が問題の条件を満たすには、これらを2進数に直した時に、
最上位桁が一致している
それぞれの桁について、の桁目との桁目が一致している、もしくはのみ0でのみ1になっている
という条件を満たす必要があります。
ということで、最上位桁が下から桁目の際ののペアを求めるために、桁DPを行います。あとはこれを全ての桁について行えばよいです。
を用意し、
:上から何桁目を見ているか(ただし最上位桁は確定しているのでないものとします)
:が以上であることが確定しているか
:が以下であることが確定しているか
とします。
あとは、下の表をもとに遷移をひたすら書いていけばよいです…
感想
の存在が邪魔で、うまい処理方法を思いつきませんでしたが、よくよく考えれば同様フラグを立てれば処理できますね…ただ桁DPの実装は丁寧にやらないといつもバグらせるので悲しいです(コンテスト中にラスト10分で書き直したものはもちろんバグだらけでした)
ABC138 E - Strings of Impurity
解法
に含まれ、に含まれない文字が存在する場合、答えは-1になります。逆に、それ以外の場合は、必ず答えを見つけることができます。
の部分列でを作る際、お互いの先頭から順番に、一致する部分を選んでいけばよいです。
作りたい文字列はと固定されているので、の文字目がの何文字目に相当するかを調べていけば、の最後の文字と対応するの番号が答えになります。
あとは、愚直にシミュレーションをしていきます。
あらかじめ、を文字の種類ごとに分け、どの文字には何文字目が含まれるか、を調べて昇順で記録しておきます。
そして、今の何文字目に居るか、というインデックスを更新しながら(初期は0文字目、としておきます)シミュレートしていきます。
次に決めるのがの文字目のとき、よりも後で登場するの場所を、先ほどの記録を二分探索して探します。よりも後ろにが存在しない場合は、の中で一番最初に存在するの場所になります。
そして、を今探した場所に更新すればよいです。
これを繰り返すと、最終的にいる位置がわかります。
そして、肝心の答えですが、先ほど以降にが存在しなかった場合、を1周することになるので、
になります。
感想
それなりにスッキリとした実装ができたので個人的に満足です。
AOJ 1604 - デッドロック検出
解法
まずは、すでにロックを獲得した資源と、次に獲得する資源を対にした頂点を作成していきます。
10個程度しか資源は存在しないので、ビットで情報を持たせることができます。
その後、2つの頂点を選んだときのパターンを見ると、今回は3パターンします。
2つの頂点どちらも既にロックを獲得した資源が存在しているパターン
2つの頂点が同時に存在することはないので、無視してかまいません。2つの頂点どちらも既にロックを獲得した資源が存在せず、片方の頂点が所有している資源をもう片方の頂点が次に獲得するパターン
片方(青い方)はこれ以降資源を獲得することはできませんが、もう片方(黄色)は次の資源を獲得することができます。この2つの頂点は、和集合の資源を獲得した状態で、次に黄色のNEXTの部分の資源を獲得しにいく1つの頂点とみなすことができます。2つの頂点どちらも既にロックを獲得した資源が存在せず、お互いの頂点が、相手が所有している資源を次に獲得するパターン
言うまでもなくデッドロックが発生します。2つの頂点どちらも既にロックを獲得した資源が存在せず、お互いが次に獲得する資源はどちらも所有していない資源のパターン
お互いが影響しあうことはないので、無視できます。
全てのパターンについて、tps://onlinejudge.u-aizu.ac.jp/problems/1604)
提出コード
解法
まずは、すでにロックを獲得した資源と、次に獲得する資源を対にした頂点を作成していきます。
10個程度しか資源は存在しないので、ビットで情報を持たせることができます。
その後、2つの頂点を選んだときのパターンを見ると、今回は3パターンします。
2つの頂点どちらも既にロックを獲得した資源が存在しているパターン
2つの頂点が同時に存在することはないので、無視してかまいません。2つの頂点どちらも既にロックを獲得した資源が存在せず、片方の頂点が所有している資源をもう片方の頂点が次に獲得するパターン
片方(青い方)はこれ以降資源を獲得することはできませんが、もう片方(黄色)は次の資源を獲得することができます。この2つの頂点は、和集合の資源を獲得した状態で、次に黄色のNEXTの部分の資源を獲得しにいく1つの頂点とみなすことができます。2つの頂点どちらも既にロックを獲得した資源が存在せず、お互いの頂点が、相手が所有している資源を次に獲得するパターン
言うまでもなくデッドロックが発生します。2つの頂点どちらも既にロックを獲得した資源が存在せず、お互いが次に獲得する資源はどちらも所有していない資源のパターン
お互いが影響しあうことはないので、無視できます。
全てのパターンについての判定がこれで網羅できるようになるので、あとは複数頂点が1つの頂点にまとめられる回数、つまり10回程度、任意の2頂点について操作を行うということを繰り返せば、デッドロックが起こるかどうかを判定できます。
感想
資源数が少ないので状態を頂点にするという発想まではよかったのですが、それ以降どうすればいいかわかりませんでした…
AOJ 2642 - 夕食
解法
日間で、日目に自炊を行ったと仮定します。
このとき、得られる幸福度は以下のようになります。
はじめの2つの項が食堂で食べることによって得られる幸福度、最後のΣの部分が自炊によって得られる幸福度になります。
これを式変形するとこうなります。
これを整えると、以下のようになります。
よって、自炊を行った日数を決め打ちしたときの幸福度の最大値は、を最小にしたときになります。
この値は、の選び方に依存しますが、を昇順にソートし、小さい順に選んでいけばよいです。
あとは、自炊を行った日数を全探索し、幸福度の最大値を求めれば答えとなります。
感想
とりあえず条件を立式して考える、できたとしても上手く答えにたどり着くかどうか微妙なところですね…