<?xml version="1.0" encoding="UTF-8" ?><rdf:RDF 
  xmlns="http://purl.org/rss/1.0/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:atom="http://www.w3.org/2005/Atom"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xml:lang="ja">
  <channel rdf:about="http://w.atwiki.jp/mi_sawa/">
    <title>メモ帳</title>
    <link>http://w.atwiki.jp/mi_sawa/</link>
    <atom:link href="https://w.atwiki.jp/mi_sawa/rss10.xml" rel="self" type="application/rss+xml" />
    <atom:link rel="hub" href="https://pubsubhubbub.appspot.com" />
    <description>メモ帳</description>

    <dc:language>ja</dc:language>
    <dc:date>2013-03-27T02:17:09+09:00</dc:date>
    <utime>1364318229</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/159.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/158.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/157.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/156.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/155.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/154.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/153.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/152.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/151.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/150.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/159.html">
    <title>全体公開/合同練習会/20130323/L 平面上の蛇</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/159.html</link>
    <description>
      *問題の概要
01のグリッドがある.
1の列であり, 列の最初と最後以外はちょうど2つ1と接しているようなものを蛇と言う.
つまり, 分岐がなく, 環状でもない列で, 周りが0なものである.
0を1に変える事で, 蛇を(他の蛇とくっつけずに)伸ばせないようなものを最大蛇という.
最大蛇の個数を数えよ. 

**実装の方針, 注意点
#region()
連結成分毎に, 最大蛇であるか調べる.
デバッグの都合を考え, 最初に各連結成分に異なる整数を割り当てた. (バグが出なかったので必要無かったが.)

蛇であるかは,
- 1つ以下と接しているマスが1つか2つ. (これが頭になる.)
- それ以外のマスは2つと接している.
の条件をチェックすればよい.

最大蛇であるかは, 頭の周りの空白マスを1にした時, それが頭の条件を満たすか否かをチェックすればよい.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
typedef complex&lt;int&gt; P;
#define X real()
#define Y imag()
P dirs[] = { P(1, 0), P(0, 1), P(-1, 0), P(0, -1), };
namespace std{
    bool operator&lt;(const P &amp;p1, const P &amp;p2) {
        return p1.X == p2.X ?  p1.Y &lt; p2.Y : p1.X &lt; p2.X;
    }
};

// pos と同じ色で連結している所を, color で塗る.
set&lt;P&gt; coloring(vvi &amp;in, P pos, int color){
    int bck = in[pos.X][pos.Y];
    in[pos.X][pos.Y] = color;
    set&lt;P&gt; res;
    res.insert(pos);
    rep(dir, 4){
        P npos = pos + dirs[dir];
        if(in[npos.X][npos.Y] == bc    </description>
    <dc:date>2013-03-27T02:17:09+09:00</dc:date>
    <utime>1364318229</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/158.html">
    <title>全体公開/合同練習会/20130323/K 等式</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/158.html</link>
    <description>
      *問題の概要
x, y, zを変数として持ち, 演算は+と*のみであるようなものが左辺に現れ, 右辺は100以下の正整数であるような式が与えられる.
これを満足する正整数x, y, zの組み合わせの総数を答えよ.

**実装の方針, 注意点
#region()
x, y, zをそれぞれ1から100まで変化させ, 全パターン調べる.
但し, 式に出てこない変数は固定する.

100^3回もstringからパースすると重いので, 各項について, 係数と, 変数のべきを先に調べておく.

&#039;&#039;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx+1=1&#039;&#039; に対する答えが &#039;&#039;0&#039;&#039; である事に注意せよ.
intで計算していると, オーバーフローし, xが2の倍数の時, 等号が成立してしまう.
大きくなってきたらダメと判定するか, double等で判定する必要がある.
#endregion

*ソースコード
&amp;bold(){Not verified}
#region(close)
#codehighlight(linenumber,cpp){{{{{{
bool inRange(int a, int x, int b){
    return a &lt;= x &amp;&amp; x &lt; b;
}
bool solve(){
    string s;
    getline(cin, s);
    if(s[0] == &#039;.&#039;) return false;

    vvi term(3, vi(1)); // 各変数の i 項目のべき
    vi c(1);            // i 項目の係数
    int use[3] = {};
    int n = 0;
    int ans = 0;
    for(int p = 0; ; ++p){
        if(s[p] == &#039;+&#039; || s[p] == &#039;=&#039;){
            if(!c[n]) c[n] = 1;
            ++n;
            if(s[p] == &#039;+&#039;){
                rep(i, 3) term[i].pb(0);
               </description>
    <dc:date>2013-03-28T15:14:15+09:00</dc:date>
    <utime>1364451255</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/157.html">
    <title>全体公開/合同練習会/20130323/J アレルギーテスト</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/157.html</link>
    <description>
      *問題の概要
アレルゲンを投与し, アレルギー反応が出るか否かで, どの物質に対してアレルギーがあるかを調べる.
アレルゲンは一日一回, 一個のみ投与でき, 投与してから $$d_i$$ 日間アレルゲンが活性化し, アレルギー反応が出る.
全てのアレルギーを調べられるような, 反応結果を見ながらではない, 最短の投与の計画を作りたい.
最短で何日かかるか. 

**実装の方針, 注意点
#region()
各物質につき, 少なくとも1日は, ｢その物質のみアレルゲンが活性化する｣ような期間が必要.
bitDPする.
&#039;&#039;dp[既に調べたやつの集合][ラストで重ねてもよい日数]=最短の終了日数&#039;&#039; なる配列を用いた.
例えば, 4, 2の順で投与した場合, 4--2-と投与し, 5日で終了し, 2の物のみが活性化するのは5日目のみなので, この後のテストを重ねてもよい日数は0.
4, 3と投与した場合は, 4--3--となり, 6日で終了し, 3の物のみが活性化するのが5, 6日目と二日間ある為, この後のテストを6日から初めて良く, 重ねてよい日数は1.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
int dp[1&lt;&lt;20][8];
int in[21];
bool solve(){
    int k;
    cin &gt;&gt; k;
    if(!k) return false;
    rep(i, k) cin &gt;&gt; in[i];

    rep(A, 1&lt;&lt;k) rep(i, 8) dp[A][i] = INF;
    dp[0][0] = 0;

    rep(A, 1&lt;&lt;k) rep(diff, 8){
        rep(i, k) if(!(A&gt;&gt;i&amp;1)){
            int nex = max(dp[A][diff]+1, dp[A][diff]-diff+in[i]);
            int nexd = nex - (dp[A][diff]+1);
            mineq(dp[A|(1&lt;&lt;i)][nexd], nex);
        </description>
    <dc:date>2013-03-27T01:06:14+09:00</dc:date>
    <utime>1364313974</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/156.html">
    <title>全体公開/合同練習会/20130323/I 彫像</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/156.html</link>
    <description>
      *問題の概要
8*8のボードの左下に居る8近傍に動けるMが, 右上を目指す.
ボードには彫像がいくつかあり, Mが動くと共に, 1だけ下に動く(一番下からは消える).
Mは, 彫像の居るマスには動けず, また, 彫像が上から来ると死ぬ.
右上に行けるか. 

**実装の方針, 注意点
#region()
kターン目(0-base)にpに彫像があるか &lt;=&gt; 0ターン目に, pから上kマス行った所に彫像があるか
に注意する.
&#039;&#039;dp[ターン数][X座標][Y座標]=そのターンその場所に行けるか&#039;&#039; なる配列を用いた.
7ターン目に生き残っていればOKだが, OKなら, どうせ30ターンもすれば, 右上まで辿り着くので, 適当にターンを回しておく.

配列を使いまわし, メモリ使用量を O(盤面の大きさ^2 * ターン数) から O(盤面の大きさ^2) にする事も可能だが, そこまでする必要は無い.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
typedef complex&lt;int&gt; P;
P dirs[] = {
    P(0, 0),
    P(1, 0), P(0, 1), P(-1, 0), P(0, -1),
    P(1, 1), P(1,-1), P(-1, 1), P(-1, -1),
};
#define X real()
#define Y imag()
namespace std{
    bool operator&lt;(const P &amp;a, const P &amp;b){
        return a.X == b.X ? a.Y &lt; b.Y : a.X &lt; b.X;
    }
};
bool inBoard(P p){
    return 0 &lt;= p.X &amp;&amp; p.X &lt; 8 &amp;&amp;
           0 &lt;= p.Y &amp;&amp; p.Y &lt; 8;
}
bool solve(){
    set&lt;P&gt; statue;
    rep(i, 8){
        rep(j, 8){
            char c; cin &gt;&gt; c;
           </description>
    <dc:date>2013-03-27T01:00:02+09:00</dc:date>
    <utime>1364313602</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/155.html">
    <title>全体公開/合同練習会/20130323/H 良い連立政権</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/155.html</link>
    <description>
      *問題の概要
安定した連立政権を作りたい.
各党が獲得した議席数(足すと150)と, 連立政権からの離脱率が与えられる.
76議席以上になる組み合わせで, 一党も連立政権から離脱しない確率が最も高くなるようにした場合, その確率を求めよ.

**実装の方針, 注意点
#region()
連立政権にある党 $$i$$ が加わると, 議席数は $$s_i$$ 増え, 一党も連立政権から離脱しない確率は $$p_i$$ 倍される.
議席数でDPする.
&#039;&#039;dp[何番目の党まで考慮したか][合計の議席数]=最も高い確率&#039;&#039; なる配列を用いた.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
bool solve(){
    int n; cin &gt;&gt; n;
    vector&lt;vector&lt;double&gt; &gt; dp(n+1, vector&lt;double&gt;(160, 0));
    dp[0][0] = 1;
    rep(i, n){
        int s, p; cin &gt;&gt; s &gt;&gt; p;
        dp[i+1] = dp[i];
        rep(t, 160) if(t+s &lt; 160){
            maxeq(dp[i+1][t+s], dp[i][t] * (p / 100.0));
        }
    }
    double res = 0;
    for(int t = 76; t &lt; 160; ++t) maxeq(res, dp[n][t]);
    cout &lt;&lt; res*100 &lt;&lt; endl;
    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </description>
    <dc:date>2013-03-27T00:17:25+09:00</dc:date>
    <utime>1364311045</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/154.html">
    <title>全体公開/合同練習会/20130323/G エレベータの故障</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/154.html</link>
    <description>
      *問題の概要
壊れて, 上にはu階, 下にはd階しか下がれないエレベータがある.
下は1階から, 上はf階まであり, それらを超えた所は指定出来ない.
s階からg階まで, 最短でどれだけで着けるか. 

**実装の方針, 注意点
#region()
既に訪れた階を省いた, 幅優先探索をする.
初期化や既に訪れた階の判定のやりやすさから, &#039;&#039;d[階数]=最短ボタン押下回数+1&#039;&#039; なる配列を用いた.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
bool inRange(int a, int x, int b){
    return a &lt;= x &amp;&amp; x &lt; b;
}

bool solve(){
    int f, s, g, up, dn;
    cin &gt;&gt; f &gt;&gt; s &gt;&gt; g &gt;&gt; up &gt;&gt; dn;
    if(!f) return false;

    int d[1000010] = {};
    d[s] = 1;

    queue&lt;int&gt; q;
    q.push(s);

    while(!q.empty()){
        s = q.front(); q.pop();
        if(inRange(1, s-dn, f+1) &amp;&amp; !d[s-dn]){
            d[s-dn] = d[s] + 1;
            q.push(s-dn);
        }
        if(inRange(1, s+up, f+1) &amp;&amp; !d[s+up]){
            d[s+up] = d[s] + 1;
            q.push(s+up);
        }
    }
    if(d[g]){
        cout &lt;&lt; d[g]-1 &lt;&lt; endl;
    }else{
        cout &lt;&lt; &quot;use the stairs&quot; &lt;&lt; endl;
    }
    return true;
}
}}}}}}
#endregion

&amp;    </description>
    <dc:date>2013-03-27T00:17:45+09:00</dc:date>
    <utime>1364311065</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/153.html">
    <title>全体公開/合同練習会/20130323/F 頑固なヌーRick</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/153.html</link>
    <description>
      *問題の概要
Rickたちヌーの群れが, ある方角FSを目指している.
FSに向かうにあたり, いくつかの餌場があり, それらを直線でつないだ経路で進む.
経路の隣合う餌場は, 距離がd以下でなければならない.
また, 餌場では90度より向きを変えてはならない.
更に, 常にFSの方角から90度以下を向いていなければならない.
これらの条件を満たす餌場のうち, 変える向きが最小な所に向かう.
この時, Rickたちはどのように動くだろうか. 

**実装の方針, 注意点
#region()
(符号無し)角度の大小 &lt;=&gt; cosの大小の逆
であり, 90度との比較は正負でわかる為, cos で処理する.
また, 念の為, 比較は小さい正数EPSを噛ませて行った.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
typedef complex&lt;double&gt; P;
#define X real()
#define Y imag()
double dot(P a, P b){
    return (a * conj(b)).X;
}
double dist(P a, P b){
    return abs(a - b);
}
double costheta(P a, P b){
    a /= abs(a);
    b /= abs(b);
    return dot(a, b);
}
bool solve(){
    P fs;
    cin &gt;&gt; fs.X &gt;&gt; fs.Y;
    int n; cin &gt;&gt; n;
    int s; cin &gt;&gt; s;
    double d; cin &gt;&gt; d;
    if(!n) return false;

    vector&lt;P&gt; in(n);
    rep(i, n) cin &gt;&gt; in[i].X &gt;&gt; in[i].Y;

    --s;
    P dir = fs;

    vector&lt;int&gt; res(1, s);
    while(true){
        pair&lt;double, in    </description>
    <dc:date>2013-03-27T00:17:53+09:00</dc:date>
    <utime>1364311073</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/152.html">
    <title>全体公開/合同練習会/20130323/E 戦艦ゲーム</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/152.html</link>
    <description>
      *問題の概要
二人のプレイヤーが, 自分の領域に, 戦艦を置いている.
各プレイヤーが座標を指定し, 相手がそこに戦艦をおいていれば撃破する.
置いていない場合, 又は, 相手の戦艦が無くなった場合は, 交代する.
速く相手の戦艦を消したほうが勝ちだが, 同じターン数で相手の戦艦を無くした場合, 又は, 両方残った場合は引き分けとする.
戦艦の位置と, 指定された座標が与えられるので, シミュレートし, どちらの勝ちか判定せよ.
但し, 勝敗の決した後も座標が与えられる可能性もある.

**実装の方針, 注意点
#region()
座標系に注意する.
とりあえず全部シミュレートし, クリアしたターンで比較して, 速い方が勝ちという事にする.
ターンは, プレイヤー交代毎に1増えるようにするが, クリアターンはそれを2で割り, 切り捨てたものとする.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
bool solve(){
    int w, h, n;
    cin &gt;&gt; w &gt;&gt; h &gt;&gt; n;

    vector&lt;vector&lt;string&gt; &gt; board(2, vector&lt;string&gt;(h));
    int rest[2] = {};
    rep(t, 2) rep(i, h) cin &gt;&gt; board[t][h-i-1];
    rep(t, 2) rep(i, h) rep(j, w) if(board[t][i][j] == &#039;#&#039;)
        ++rest[t];

    int t = 0, turn_num = 0;
    int end_turn[2] = {INF, INF};
    while(n--){
        int x, y;
        cin &gt;&gt; y &gt;&gt; x;
        if(board[!t][x][y] == &#039;#&#039;){
            board[!t][x][y] = &#039;.&#039;;
            --rest[!t];
            if(rest[!t]) continue;    </description>
    <dc:date>2013-03-27T00:18:15+09:00</dc:date>
    <utime>1364311095</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/151.html">
    <title>全体公開/合同練習会/20130323/D 恋人同士の移動時間</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/151.html</link>
    <description>
      *問題の概要
平面上に, x軸 又は y軸に平行な線分が壁として一本与えられる.
また, 2人が居る点が与えられる.
彼らが会うのにかかる最短時間を求めよ.
ただし, 壁は超えられず, 壁上の両側では会った事にならず, 1単位距離動くのに1単位時間かかる.

**実装の方針, 注意点
#region()
二人の位置を $$A, B$$ とし, 壁を $$PQ$$ とする.
$$AB$$ と $$PQ$$ が交わる場合, $$AP+PB, AQ+QB$$ の短い方, そうでない場合は $$AB$$ が通る道になる.

線分と線分の交差判定ライブラリは, [[Spaghetti Source&gt;http://www.prefield.com/algorithm/index.html]] を参考に.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
typedef complex&lt;double&gt; P;
#define X real()
#define Y imag()
double dot(P a, P b){
    return (a * conj(b)).X;
}
double cross(P a, P b){
    return (a * conj(b)).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b, c) &gt; 0)     return +1;
    if(cross(b, c) &lt; 0)     return -1;
    if(dot(b, c) &lt; 0)       return +2;
    if(norm(b) &lt; norm(c))   return -2;
    return 0;
}
double dist(P a, P b){
    return abs(a - b);
}
bool intersectSS(const vector&lt;P&gt; &amp;a, const vector&lt;P&gt; &amp;b){
    return ccw(a[0], a[1], b[0]) * ccw(a[0],     </description>
    <dc:date>2013-03-27T00:18:24+09:00</dc:date>
    <utime>1364311104</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/150.html">
    <title>全体公開/合同練習会/20130323/C センサー付きロボット</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/150.html</link>
    <description>
      *問題の概要
次の3つの命令を受け付けるロボットが居る.
- F: 前へ1単位進む.
- R: 右へ90度回転する.
- L: 左へ90度回転する.
但し, 壁があり, Fで壁に追突する場合は, 前に進む代わりに, 180度回転する.
壁はx, y軸のいずれかに平行に置かれ, 壁同士は接続され, 1つの多角形になっている.
壁, 初期位置, 命令が与えられるので, 最終位置と, ロボットの初期位置からの(ユークリッド)距離で最も離れた点を答えよ.
複数ある場合は, y座標の大きい方, それも複数あればx座標の大きい方.

**実装の方針, 注意点
#region()
座標や向きを, 複素数で管理する.
今の向きから, 右を向くには $$-i$$, 左を向くには $$i$$ を掛ければよい.

出力の2つ目は, (初期位置からの距離の二乗, y座標, x座標) が辞書順で最も大きくなるような点.
距離そのままでも良いが, &#039;&#039;complex&lt;int&gt;&#039;&#039; では &#039;&#039;abs()&#039;&#039; は異なる動きをするので, 距離の二乗である &#039;&#039;norm()&#039;&#039; を用いる.

壁は, 壁である全ての点を &#039;&#039;set&lt;P&gt;&#039;&#039; に入れて管理した.
&#039;&#039;set&lt;P&gt;&#039;&#039; を使うため, 比較関数の実装が必要.
ついでに, 出力の2つ目を作るのが楽なように, (y座標, x座標) の辞書順で順序を入れた.
これにより, (初期位置からの距離の二乗, その点) が辞書順で大きいものを選べばよく, &#039;&#039;pair&lt;int, P&gt;&#039;&#039; で管理すると楽になる.

また, &#039;&#039;p(x1, y1)&#039;&#039; と &#039;&#039;q(x2, y2)&#039;&#039; を結ぶ壁は, x座標が区間 &#039;&#039;[min(x1, x2), max(x1, x2)]&#039;&#039;, y座標が区間 &#039;&#039;[min(y1, y2), max(y1, y2)]&#039;&#039; に入る点全体である事に注意すると,
x軸に平行か, y軸に平行か, どちらが右/上にあるか等で場合分けせずに済む.
#endregion

*ソースコード
&amp;bold(){Not verified}
#region(close)
#codehighlight(linenumber,cpp){{{{{{
typedef complex&lt;int&gt; P;
    </description>
    <dc:date>2013-03-28T14:34:07+09:00</dc:date>
    <utime>1364448847</utime>
  </item>
  </rdf:RDF>
