<?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>2015-03-11T11:30:57+09:00</dc:date>
    <utime>1426041057</utime>

    <items>
      <rdf:Seq>
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/113.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/112.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/148.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/150.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/56.html" />
                <rdf:li rdf:resource="https://w.atwiki.jp/mi_sawa/pages/159.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/147.html" />
              </rdf:Seq>
    </items>
	
		
    
  </channel>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/113.html">
    <title>競技プログラミング/C++/STL/complex</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/113.html</link>
    <description>
      ----
#contents()

----
*複素数型
複素数型.~
使うには, &#039;&#039;#include&lt;complex&gt;&#039;&#039; が必要.~
&#039;&#039;std::complex&lt;T&gt;&#039;&#039; で, &#039;&#039;T&#039;&#039; を要素似持つ複素数クラスを使える.~
すなわち, $$a + b\sqrt{-1}\ (a, b \in T)$$ なる要素を扱える.~
但し, &#039;&#039;T&#039;&#039; として有効なのは &#039;&#039;float&#039;&#039;, &#039;&#039;double&#039;&#039;, &#039;&#039;long double&#039;&#039; のみで, 他は未定義.
#codehighlight(linenumber, cpp){{{{{{
#include &lt;complex&gt;
#include &lt;iostream&gt;
using namespace std;
int main(void){
    complex&lt;double&gt; a(1, 0), i(0, 1);   //aは1+0\sqrt{-1}, iは0+1\sqrt{-1}
    cout &lt;&lt; a * i * i + 1.0 &lt;&lt; endl;    // =&gt; (0, 0)
    cout &lt;&lt; conj(i) &lt;&lt; endl;            // =&gt; (0, -1) : 共役
    cout &lt;&lt; abs(a+i) &lt;&lt; endl;           // =&gt; 1.41421 : 絶対値
    cout &lt;&lt; norm(a+i) &lt;&lt; endl;          // =&gt; 2       : 絶対値^2
    return 0;
}
}}}}}}

----
*平面幾何
&#039;&#039;complex&#039;&#039; は複素数型であるが, 競技プログラミングでは, 複素数を扱うより, むしろ二次元ベクトルとして利用する事が多い.~
対応は, 複素平面を考えればわかるだろう.~
但し, &#039;&#039;complex&lt;double&gt; + double&#039;&#039; のような操作も valid になってしまうので, コーディングミスに注意する必要がある.~
平面幾何の基礎的な要素として, 内積と外積があるが, これらは, 複素数の積と, 共役を使うと簡単に書ける.
#codehighlight(linenumber, cpp){{{{{{
#include &lt;complex&gt;
#include &lt;iostream&gt;
using namespace std;

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 main(void){
    P a(0, 1), b(20, 1);
    cout &lt;&lt; dot(a, b) &lt;&lt; endl;    //=&gt;  1  : 内積
    cout &lt;&lt; cross(a, -b) &lt;&lt; endl; //=&gt; -20 : 外戚ベクトルの(方向を含めた)大きさ.
    return 0;
}
}}}}}}

----
*格子
&amp;bold(){以下のは使っちゃダメ!!!!}~
普通, &#039;&#039;complex&lt;T&gt;&#039;&#039; の &#039;&#039;T&#039;&#039; って &#039;&#039;double&#039;&#039; 以外入れる余地ないだろという感じがするが, &#039;&#039;complex&lt;int&gt;&#039;&#039; も意外に使える.~
格子点を動く問題や, ボードゲームでの駒の位置など, 2つの整数の組で表すものに使うと, &#039;&#039;pair&lt;int, int&gt;&#039;&#039; に比べ, 足し算があるなど, メリットもある.(デメリットもあるが.)~
よく &#039;&#039;隣合う点に移動出来る&#039;&#039; とか, &#039;&#039;隣の点&#039;&#039; 系の問題があるが, (complexを使うか否かに限らず) 相対座標で隣の点を列挙しておくと便利である.~
&#039;&#039;隣&#039;&#039; の定義でよく用いられるのは十字型の4つ(四近傍とも)であるが, 斜めも入れた八近傍(将棋の王の動き)を考える場合もあり, その場合は P(±1, ±1)の4つを加えればよい.~
また, $$P(0, 1)$$ を掛けると90度回転する事も覚えておくとよい.(複素平面で考えれば明らか).
#codehighlight(linenumber, cpp){{{{{{
#include &lt;complex&gt;
#include &lt;iostream&gt;
using namespace std;

typedef complex&lt;int&gt; P;
P dirs[] = { P(1, 0), P(0, 1), P(-1, 0), P(0, -1) };
// complexを使わない場合は, 例えば
// int dx[] = {1, 0, -1, 0};
// int dy[] = {0, 1, 0, -1};
// などとするとよい.

int main(void){
    P p(3, 0);
    for(int d = 0; d &lt; 4; ++d){
        cout &lt;&lt; (p + dirs[d]) &lt;&lt; endl;
    }
}
}}}}}}

----
*比較演算子
&#039;&#039;complex&#039;&#039; には &#039;&#039;&lt;&#039;&#039; が定義されていない(自然な順序が無い)ため, そのままでは &#039;&#039;set&#039;&#039; や &#039;&#039;map&#039;&#039; のキーとして使う事が出来ない.~
キーにしたければ, 例えば次のように定義してやればよい.
#codehighlight(linenumber, cpp){{{{{{
#include &lt;complex&gt;
#include &lt;iostream&gt;
#include &lt;set&gt;
using namespace std;

namespace std{
    template&lt;class T&gt; bool operator&lt;(const complex&lt;T&gt; &amp;a, const complex&lt;T&gt; &amp;b){
        return a.real() == b.real() ? a.imag() &lt; b.imag() : a.real() &lt; b.real();
    }
};
typedef complex&lt;int&gt; P;
#define X real()
#define Y imag()
int main(void){
    set&lt;P&gt; a;
    a.insert(P(1, 0));
    return 0;
}
}}}}}}


&amp;link_edit()    </description>
    <dc:date>2015-03-11T11:30:57+09:00</dc:date>
    <utime>1426041057</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/112.html">
    <title>競技プログラミング/C++/STL</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/112.html</link>
    <description>
      ----
*別ページにあるもの
#ls3()

----
*このページにあるもの
#contents(fromhere=true)

----
*STL
スタンダード・テンプレート・ライブラリ.~
テンプレートを使ったライブラリとか.~
ここに分類すべきでない気もするけれど, いろんなものの基本になってるのが, iterator.~

**iterator
ここでの説明は割と語弊があるというか, 真実でない事も含むが, まぁだいたいそんな感じと思っていてもそんなに問題ないという感じ.~
日本語では反復子とか言う.~
要素を指していて, &#039;&#039;++&#039;&#039;で次, &#039;&#039;--&#039;&#039;で前の要素に移り, 単項の&#039;&#039;*&#039;&#039;でその要素自体にアクセスする.~
ポインタに似てる.~
&#039;&#039;#include &lt;algorithm&gt;&#039;&#039; とかすると, イテレータを使ったいくつかのアルゴリズムを使える.~
例えば,
#codehighlight(linenumber, cpp){{
int data[10] = {2, 1, 3, 7, 6, 0, 9, 4, 5, 8};
sort(data, data+10);
}}
でソート出来る.~
後述するvectorとか使うなら,
#codehighlight(linenumber, cpp){{
vector&lt;int&gt; v;
// vに対して色々操作して, 要素入れたりとかする.
sort(v.begin(), v.end());
}}
STLコンテナは, 基本的に, &#039;&#039;begin()&#039;&#039; で最初の要素を指すイテレータ, &#039;&#039;end()&#039;&#039; で最後の要素の後ろを指すイテレータが取れる.~
つまり, &#039;&#039;v[0] == *v.begin()&#039;&#039; で, &#039;&#039;v[v.size()-1] == *(v.end()-1)&#039;&#039; 的な関係になっている.~

ややこしいが, &#039;&#039;++&#039;&#039;で前の要素を指し, &#039;&#039;--&#039;&#039;で後ろの要素を指すという, 逆順のイテレータもあって, &#039;&#039;rbegin()&#039;&#039; で一番後ろ, &#039;&#039;rend()&#039;&#039; で一番前の前を指すイテレータが取れる.~
これで何が便利かというと,
#codehighlight(linenumber, cpp){{
vector&lt;int&gt; v;
// vにいろいろ操作する
sort(v.rbegin(), v.rend());
}}
で, vを逆順ソート出来たりするところである.~

他にもいくつかのアルゴリズムが使えるので, 詳しくはリンクの所とか, ググったりとかしてください.~
よく使うのは, ソート済みのものを二分探索する, &#039;&#039;upper_bound&#039;&#039;, &#039;&#039;lower_bound&#039;&#039;とか, &#039;&#039;next_permutation&#039;&#039;とか. 

**pair
よく使う.~
&#039;&#039;pair&lt;T, U&gt;&#039;&#039; で型Tと型Uのペアを型にした感じのものが扱える.~
&#039;&#039;first&#039;&#039; と &#039;&#039;second&#039;&#039; で要素にアクセス出来る.~
要素間には, 大小関係が定義されていて, &#039;&#039;a &lt; b&#039;&#039; は &#039;&#039;(a.first &lt; b.first) or ((a.first == b.first) and (a.second &lt; b.second))&#039;&#039;と同値.(すなわち, 辞書順).~
ソートとかするときに便利.~
&#039;&#039;make_pair(a, b)&#039;&#039; で, &#039;&#039;pair&lt;aの型, bの型&gt;&#039;&#039; なる型の, &#039;&#039;first == a; second == b&#039;&#039; になるペアを作れる.

#codehighlight(linenumber, cpp){{
#include&lt;utility&gt;
using namespace std;
int main(void){
   pair&lt;string, int&gt; b(&quot;foo&quot;, 20);
   cout &lt;&lt; b.first &lt;&lt; &quot;, &quot; &lt;&lt; b.second;
   b.first = &quot;bar&quot;;

   typedef pair&lt;int, int&gt; pii; //pair&lt;int, int&gt; を pii 型として定義しなおした
   pii a(1, 2), b(3, 4);
   pii c = make_pair(5, 6);
}
}}




*STL container
データを格納するやつら.
リンクのProgramming Placeとか見ると良い.
一応超基本的な所だけ書いておく.

**vector
配列に似た何か.
動的配列とか言われたりするみたい.~
要素の個数を最初にしていしなくてもよい配列と思えば, 大体あっている.~
普通の配列よりは遅いので, 時間がシビアな時は配列に書き換えた方がよい.(が, あんまり気にしないで大丈夫)~
コピーとかはなるべくしない方がよい.~
ランダムアクセスと, 最後に要素を追加する / 最後の要素を削除する操作が, 比較的高速に出来る.
#codehighlight(linenumber, cpp){{
#include &lt;vector&gt; // こいつが必要
#include &lt;iostream&gt;
using namespace std; // 本当は std::vectorだが, これでvectorだけで良くなる.
int main(void){
    vector&lt;int&gt; v;          //中身がint型のvector
    vector&lt;int&gt; v1(10);     //要素が10個すでにあるvector(要素は0で初期化されている)
    vector&lt;int&gt; v2(10, -1); //要素が10個で, 全部-1なvector
    vector&lt;int&gt; v3(v1.begin(), v1.end()) // v1と中身が同じvector
    int data[3] = {2, 1, 3};
    vector&lt;int&gt; v4(data, data+3); //中身が2, 1, 3なvector

    for(int i = 0; i &lt; 10; ++i) v.push_back(i);  // v1の末尾に0, 1, ..., 9を追加.
    for(int i = 0; i &lt; v1.size(); ++i) cout &lt;&lt; v[i] &lt;&lt; &quot;, &quot;; // v1の要素を出力
    cout &lt;&lt; endl;
    while(v1.size() != 0) v.pop_back(); //v1の要素を後ろから順に削除

    vector&lt;string&gt; vs; //要素がstring型のvector.
    vs.push_back(&quot;Hello&quot;);
    vs.push_back(&quot;world!&quot;);
    for(int i = 0; i &lt; vs.size(); ++i) cout &lt;&lt; vs[i] &lt;&lt; &quot;, &quot;;
    cout &lt;&lt; endl;
    return 0;
}
}}
とか.~

**map
配列の, 添字(v[0]の0みたいなやつ) が, 自然数でなくても良くなったバージョン的な感じ.~
中身はともかくとして, 他の言語で連想配列とか, ハッシュとか, ハッシュマップとか言われているのと同じようなもの.~
同じ添字に複数のアイテムを入れることは出来ない. (それが可能なmultimapというのもあるが, 僕は使ったことない)~

#codehighlight(linenumber, cpp){{
#include &lt;map&gt;
#include &lt;iostream&gt;
using namespace std; //mapもstd::map.
int main(void){
    map&lt;string, int&gt; msi; //添字がstringで, 要素がintなmap
    msi[&quot;hoge&quot;] = 0;
    msi[&quot;foo&quot;] = 1;
    msi.insert(pair&lt;string, int&gt;(&quot;fizz&quot;, 2)); //こんな要素の追加のしかたもある.(pairの項を見よ)
    cout &lt;&lt; msi.count(&quot;hoge&quot;) &lt;&lt; endl; // &quot;hoge&quot; がキーになっている要素は1つあるので, 1.(mapは1か0しか返さないはず)
    cout &lt;&lt; msi.count(&quot;aaa&quot;) &lt;&lt; endl; // 0になる.
    for(map&lt;string, int&gt;::iterator it = msi.begin(); it != msi.end(); ++it) { //map&lt;string, int&gt; のイテレータは, map&lt;string, int&gt;::iterator型.
        cout &lt;&lt; (*it).first &lt;&lt; &quot;: &quot; &lt;&lt; (*it).second &lt;&lt; endl; //mapのイテレータは, firstにキー, secondに値を格納している. (pairの項を見よ)
    }
}
}}
mapのイテレータによるアクセスでは, 常に順序がソート順になっている.~
基本的な操作は, 要素数を&#039;&#039;n&#039;&#039;として, &#039;&#039;O(log n)&#039;&#039; なので, ちょっとだけ遅いが, そんなに気にする程度ではない.~
キーになるクラスには, 大小関係が定義されている(具体的には, 全順序関係で, &#039;&#039;operator&lt;&#039;&#039;が定義されている) 必要がある.~

**set
集合型.~
mapと同様, 常に中身はソートされている.~
xを要素として含むか否か, 要素の追加, 削除が出来る.
#codehighlight(linenumber, cpp){{
#include&lt;set&gt;
#include&lt;iostream&gt;
using namespace std; //setもstd::set
int main(void){
    set&lt;int&gt; s;
    s.insert(0); //sに0が追加される
    s.insert(1); //sに1が追加される
    cout &lt;&lt; s.count(2) &lt;&lt; endl; // 0
    cout &lt;&lt; s.count(0) &lt;&lt; endl; // 1
    if(s.count(1)) s.insert(10); //sが1を含むなら, sに10が追加される
    s.erase(0); //0を削除する
}
}}
mapと同じく, 基本的な操作は&#039;&#039;O(log n)&#039;&#039;.~
要素のクラスには, 大小関係が定義されている(具体的には, 全順序関係で, &#039;&#039;operator&lt;&#039;&#039;が定義されている) 必要がある.~

**queue
**stack
**priority_queue

&amp;link_edit()    </description>
    <dc:date>2014-11-14T01:29:30+09:00</dc:date>
    <utime>1415896170</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/148.html">
    <title>全体公開/合同練習会/20130323</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/148.html</link>
    <description>
      #style(float:right;){{{{{{
|今日 | &amp;counter(today) |
|昨日 | &amp;counter(yesterday) |
|合計 | &amp;counter() |
}}}}}}

#style(float:left;){{{{{{
このページ/子ページでは,
[[第二回合同練習会&gt;http://www.ne.senshu-u.ac.jp/~matunaga/icpcwiki/index.php?Learning%2F%B9%E7%C6%B1%CE%FD%BD%AC%B2%F120130323]]
で扱われた問題に対する, @Mi_Sawa の解答を載せています.

全てが正しいとは限りません.
コメントやツッコミ等あれば, twitterか, 各ページの一番下のコメント欄でお願いします.
}}}}}}
#style(clear:both;)

----
#ls3()
----

各ページでは省くが, 次のようなコードを前提とし, &#039;&#039;solve()&#039;&#039; 関数を実装した.
(コンテスト中は, 最初に全て書くことはせず, 必要に応じて追加する.)
#codehighlight(linenumber, cpp){{{{{{
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include &lt;cmath&gt;
#include &lt;cstdlib&gt;
#include &lt;set&gt;
#include &lt;map&gt;
#include &lt;queue&gt;
#include &lt;stack&gt;
#include &lt;complex&gt;
#include &lt;iomanip&gt;

// 今回はforeachでしか用いていない.
#define let(v, x) typeof(x) v = (x)
// b &lt;= i &lt; n なる i についてループする.
#define REP(i,b,n) for(int i=(int)(b);i&lt;(int)(n);++i)
// 0 &lt;= i &lt; n なる i についてループする.
#define rep(i,n) REP(i,0,n)
#define sz(v) ((int)v.size())
// 0 &lt;= i &lt; v.size() なる i についてループする.
#define repsz(i, v) rep(i, sz(v))
// v.begin() から v.end() までイテレータを回す.
#define foreach(i,v) for(let(i, (v).begin());i!=(v).end();i++)
#define pb push_back
#define fst first
#define snd second
#define all(x) (x).begin(),(x).end()
static const int INF = 1&lt;&lt;25;
static const double EPS = 1e-5;
using namespace std;
typedef long long ll;
typedef vector&lt;int&gt; vi;
typedef vector&lt;vi&gt; vvi;
// a を a と b の小さい方で更新する.
template&lt;class T&gt; T mineq(T &amp;a, const T &amp;b){ return a = min(a, b); }
// a を a と b の大きい方で更新する.
template&lt;class T&gt; T maxeq(T &amp;a, const T &amp;b){ return a = max(a, b); }

// 各ケースについて, 解く.
// ケースの終わりでは, false を返す.
// 具体的には, 例えば, 入力の終わりに 0 が入るとかなら,
//  int n; cin &gt;&gt; n;
//  if(n == 0) return false;
//  // 問題を解く
//  return true;
// のようなコードが入る.
bool solve(){
    
    return true;
}
int main(){
    // 出力が実数な場合は, 桁数を増やす為,
    // cout.setf(ios::fixed); cout.precision(10);
    while(solve());
    // 最初にケース数が来る場合は,
    // int n;
    // cin &gt;&gt; n;
    // rep(i, n) solve();
    return 0;
}
}}}}}}

&amp;link_edit()

----
#pcomment(reply)    </description>
    <dc:date>2013-03-29T19:14:04+09:00</dc:date>
    <utime>1364552044</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);
                c.pb(0);
            }else{
                ++p;
                while(p &lt; sz(s)){
                    ans *= 10;
                    ans += s[p] - &#039;0&#039;;
                    ++p;
                }
                break;
            }
        }else if(s[p] == &#039;=&#039;){
        }else if(inRange(&#039;0&#039;, s[p], &#039;9&#039;+1)){
            c[n] *= 10;
            c[n] += s[p]-&#039;0&#039;;
        }else{
            ++term[s[p]-&#039;x&#039;][n];
            use[s[p]-&#039;x&#039;] = true;
        }
    }

    int res = 0;
    int xyz[3];
    for(xyz[0] = 1; xyz[0] &lt;= (use[0] ? 100 : 1); ++xyz[0]){
        for(xyz[1] = 1; xyz[1] &lt;= (use[1] ? 100 : 1); ++xyz[1]){
            for(xyz[2] = 1; xyz[2] &lt;= (use[2] ? 100 : 1); ++xyz[2]){
                double s = 0;
                rep(i, n){
                    double t = c[i];
                    rep(j, 3) rep(k, term[j][i]) t *= xyz[j];
                    s += t;
                }
                if(abs(s - ans) &lt; 0.5) ++res;
            }
        }
    }
    cout &lt;&lt; res &lt;&lt; endl;

    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </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/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;
#define X real()
#define Y imag()
namespace std{
    bool operator&lt;(const P &amp;p1, const P &amp;p2){
        return p1.Y == p2.Y ?  p1.X &lt; p2.X : p1.Y &lt; p2.Y;
    }
};
bool solve(){
    int n;
    cin &gt;&gt; n;
    if(!n) return false;

    // 壁の生成
    vector&lt;P&gt; wall_raw(n);
    rep(i, n) cin &gt;&gt; wall_raw[i].X &gt;&gt; wall_raw[i].Y;
    set&lt;P&gt; wall;
    rep(i, n){
        P crr = wall_raw[i];
        P nex = wall_raw[(i+1)%n];
        REP(x, min(crr.X, nex.X), max(crr.X, nex.X)+1)
            REP(y, min(crr.Y, nex.Y), max(crr.Y, nex.Y)+1)
                wall.insert(P(x, y));
    }

    P initial;
    cin &gt;&gt; initial.X &gt;&gt; initial.Y;

    P pos = initial;
    P dir = P(0, 1);
    pair&lt;int, P&gt; res(0, initial);
    string s;
    cin &gt;&gt; s;
    repsz(i, s){
        if(s[i] == &#039;F&#039;){
            if(wall.count(pos + dir)){
                // 反転
                dir *= -1;
            }else{
                // 直進
                pos += dir;
            }
        }else if(s[i] == &#039;R&#039;){
            // 右回転
            dir *= P(0, -1);
        }else if(s[i] == &#039;L&#039;){
            // 左回転
            dir *= P(0, 1);
        }
        maxeq(res, make_pair(norm(pos - initial), pos));
    }
    cout &lt;&lt; pos.X &lt;&lt; &quot; &quot; &lt;&lt; pos.Y &lt;&lt; &quot; &quot;;
    cout &lt;&lt; res.snd.X &lt;&lt; &quot; &quot; &lt;&lt; res.snd.Y &lt;&lt; endl;
    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </description>
    <dc:date>2013-03-28T14:34:07+09:00</dc:date>
    <utime>1364448847</utime>
  </item>
    <item rdf:about="https://w.atwiki.jp/mi_sawa/pages/56.html">
    <title>競技プログラミング/C++</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/56.html</link>
    <description>
      ----
*別ページにあるもの
#ls3()

----
*このページにあるもの
#contents(fromhere=true)

----
*コンパイルとか
hoge.ccをコンパイルして実行するなら,
#codehighlight(linenumber, sh){{
g++ hoge.cc
./a.exe
}}
実行ファイル名を変えたいなら,
#codehighlight(linenumber, sh){{
g++ hoge.cc -o fuga.exe
./fuga.exe
}}
最適化オプションとかつけるなら
#codehighlight(linenumber, sh){{
g++ hoge.cc -O2
}}
とか.
#codehighlight(linenumber, sh){{
g++ --help
}}
でいろいろ見られる.

----
*コメント
行コメントとブロックコメントがある.
#codehighlight(linenumber, cpp){{
int a; //これはコメント
int b;
/*
 ここはコメント
 */
int c;
}}
的な.

----
*おまじない
#codehighlight(linenumber, cpp){{
#include &lt;iostream&gt;
#define rep(i, n) for(int i = 0; i &lt; (n); ++i)
using namespace std;
typedef long long ll;
}}
とか, その他もろもろ.

**include
&#039;&#039;#include&#039;&#039;はお馴染みの, 標準ライブラリをロードするやつ.~
Cの&#039;&#039;stdio.h&#039;&#039;とか&#039;&#039;math.h&#039;&#039;とかも&#039;&#039;#include &lt;stdio.h&gt;&#039;&#039;とかでinclude出来る.~
&#039;&#039;#include &lt;cstdio&gt;&#039;&#039;とか&#039;&#039;c&#039;&#039;を先頭につけても良い.~
includeして使わないというのは別に問題ないので, プロコンでは最初に30個くらいincludeしてる人とか多い.~

**namespace
日本語では名前空間とか言う.~
これから出てくる&#039;&#039;cin&#039;&#039;とか&#039;&#039;cout&#039;&#039;とか, その他様々なやつは&#039;&#039;std&#039;&#039;というnamespaceに入っている.~
本当は&#039;&#039;std::cin&#039;&#039;とか, &#039;&#039;std::cout&#039;&#039;とかいちいち書かなければならないのを, &#039;&#039;using namespace std;&#039;&#039; することで省略できる.~

**define
Cと同じように, マクロが使える.~
慣れるとおいしい.~
最初はあんまり気にしなくていいけど, 他の人のソースを読むのに理解する必要がある.~

**typedef
型のエイリアス的な.~
上の例では, &#039;&#039;long long&#039;&#039; 型を, &#039;&#039;ll&#039;&#039;で使えるようにする.~

----
*型と変数宣言
C言語と同じように, いろいろな型がある.~
C言語と同様, &#039;&#039;型名 変数名&#039;&#039; で変数宣言する.~
C言語と違い, 割とどこでも変数宣言できる.~
#codehighlight(linenumber, cpp){{
int a = 0, b = 1;
double p = 3.14;
string s = &quot;hoge&quot;;
int arr[10] = {0, 1, 2, 3};
arr[4] = 4;
if(a == 0) b *= 2;
int d = 0;
}}

&#039;&#039;型&amp; 名前 = 同じ型の別の変数;&#039;&#039; で宣言すると, エイリアスを作ることが出来る.~
これのおかげで, あんまりポインタ使わなくてもよい感じになっている.(関数の項でもちょっと出てくる)~
#codehighlight(linenumber, cpp){{
int a = 0;
int&amp; b = a;
b = 10; //aも10になる
a = 2; //bも2になる
}}
詳しくは, &#039;&#039;C++ 参照&#039;&#039; でググるとよいです.~


----
*入出力
cinとcoutで大体なんとかなる.~
多分console input/outputの略.~
&#039;&#039;cstdio&#039;&#039;をincludeすれば&#039;&#039;printf&#039;&#039;とか&#039;&#039;scanf&#039;&#039;も使える.
#codehighlight(linenumber, cpp){{
int a, b;
string s;
char c;
cin &gt;&gt; a &gt;&gt; b &gt;&gt; s &gt;&gt; c;
cout &lt;&lt; a*b &lt;&lt; &quot;, &quot; &lt;&lt; b &lt;&lt; endl &lt;&lt; s &lt;&lt; endl;
}}
&#039;&#039;cin&#039;&#039; は &#039;&#039;&gt;&gt;&#039;&#039; という演算子を再定義していて, &#039;&#039;cin &gt;&gt; hoge&#039;&#039; とやると, hoge の型にあわせて読み込み, hogeに入れてくれる.~
さらに, cinはcin自体を返すので, &#039;&#039;cin &gt;&gt; hoge &gt;&gt; fuga&#039;&#039;とやると, hoge のあとに fuga に入力する.~
空白と改行区切りでパースされるので, 一行全体を取得したいとかいう場合は,~
#codehighlight(linenumber, cpp){{
string s;
getline(cin, s);
}}
とかで.~
coutも, 変数の型によって適当に出力してくれる.~
endlは改行. 多分 end line だと思う.~
このへんは std 内なので, using namespace std をしていないなら, &#039;&#039;std::cout &lt;&lt; a &lt;&lt; std::endl&#039;&#039; とかする.~

doubleとかを出力する時は精度がよろしくないので,
#codehighlight(linenumber, cpp){{
cout.setf(ios::fixed);
cout.precision(10);
}}
とかする.

----
*制御構造
基本的にC言語と同じ.~
**条件
比較は &#039;&#039;==&#039;&#039;, &#039;&#039;!=&#039;&#039;, &#039;&#039;&lt;=&#039;&#039;, &#039;&#039;&gt;=&#039;&#039;, &#039;&#039;&gt;&#039;&#039;, &#039;&#039;&lt;&#039;&#039;.~
and, orは &#039;&#039;&amp;&amp;&#039;&#039;, &#039;&#039;||&#039;&#039;~

#codehighlight(linenumber, cpp){{
if(a != 0 &amp;&amp; b != 0) cout &lt;&lt; &quot;a*b != 0&quot; &lt;&lt; endl;
if(a == 0 || b == 0) cout &lt;&lt; &quot;a*b = 0&quot; &lt;&lt; endl;
}}
int, longなどの整数型は, 0の場合は偽, それ以外は真とみなされる.~
#codehighlight(linenumber, cpp){{
if(a) cout &lt;&lt; &quot;a != 0&quot; &lt;&lt; endl;
a = !(!a) // aは0ならそのまま, それ以外なら1になる.
}}

**if
一行の時は, ブレース(波ガッコ:{})は付けても付けなくてもよい.~
#codehighlight(linenumber, cpp){{
if(a == 0) cout &lt;&lt; &quot;a equals to zero&quot; &lt;&lt; endl;
else if(a == 1) {
    cout &lt;&lt; &quot;a equals to one&quot; &lt;&lt; endl;
} else
    cout &lt;&lt; &quot;a*a != a&quot; &lt;&lt; endl;
}}

**switch-case
Cと同じ.~
あんまり使わない.~
breakを忘れずに.~
charとか整数とかで使える.~
#codehighlight(linenumber, cpp){{
int a, b, res;
char c;
cin &gt;&gt; a &gt;&gt; c &gt;&gt; b;
switch(c){
    case &#039;+&#039;:
        res = a + b;
        break;
    case &#039;-&#039;:
        res = a - b;
        break;
    case &#039;*&#039;:
        res = a * b;
        break;
    case &#039;/&#039;:
        res = a / b;
        break;
    default:
        res = 0;
        break;
}
cout &lt;&lt; res &lt;&lt; endl;
}}

**for
Cと同じ.~
ただし, forの最初の処理のところで変数宣言とか出来る.~
一行の時は, ブレース(波ガッコ:{})は付けても付けなくてもよい.~
#codehighlight(linenumber, cpp){{
for(int i = 0; i &lt; 10; ++i){
    cout &lt;&lt; i &lt;&lt; endl;
}
for(int i = 0; i &lt; 10; ++i){
    if(i) cout &lt;&lt; &quot;, &quot;;
    cout &lt;&lt; i;
}
cout &lt;&lt; endl;
}}
2つ目のはイディオムで, 間にスペースとかカンマとかを入れて出力したい時とかに使われる.~
(iが0の時以外, &#039;&#039;cout &lt;&lt; &quot;, &quot;;&#039;&#039; が実行される.)~

**while
Cと同じ.~
#codehighlight(linenumber, cpp){{
int n;
cin &gt;&gt; n;
while(n){
    cout &lt;&lt; n &lt;&lt; endl;
    --n;
}
do{
    cout &lt;&lt; n &lt;&lt; endl;
    --n;
}while(n &gt;= 0);
}}
どちらもnから1を表示する.~
do-while(後置while)は,
#codehighlight(linenumber, cpp){{
int n;
do{
    cin &gt;&gt; n;
}while(n % 2 != 0);
}}
のように, 最初の一回は必ず実行されて欲しい時に使う.~
上の場合, 偶数が入力されるまで入力させ続ける.~


*関数
大体はC言語と同じ.~
#codehighlight(linenumber, cpp){{
int gcd(int a, int b){
    if(b == 0) return a;
    return gcd(b, a%b);
}
}}
C言語で, gcdとlcmを一気に計算したいとか思ったら, ポインタを使って~
#codehighlight(linenumber, cpp){{
void gcdlcm(int a, int b, int* g, int* l){
    int ab = a * b;
    while(b != 0){
        a %= b;
        swap(a, b);
    }
    *g = a;
    *l = ab / *g;
}
}}
とかやるが, C++で参照を使うと, 次のように書ける.~
#codehighlight(linenumber, cpp){{
void gcdlcm(int a, int b, int&amp; g, int&amp; l){
    int ab = a * b;
    while(b != 0){
        a %= b;
        swap(a, b);
    }
    g = a;
    l = ab / g;
}
}}

----
*クラス
**演算子の再定義
英語ではオペレータのオーバーロードとか言う.
C++ 演算子 オーバーロード とかでググるとよい.
自分で作ったクラスで, &#039;&#039;a + b&#039;&#039; とかが出来るようになる.~
更に, 入出力が &#039;&#039;cin &gt;&gt; a&#039;&#039; とかで出来るように作れる.~
また, &#039;&#039;set&#039;&#039; や &#039;&#039;map&#039;&#039; のキーにする時は, 比較演算子を再定義する必要がある.~

----
*string
リンクのProgramming Placeとか見ると良い.

----
*テンプレート
例えば, 絶対値を返す, my_absという関数を作りたいとする.
#codehighlight(linenumber, cpp){{
int my_abs(int n){ return n &gt; 0 ? n : -n; }
}}
しかし, 数値の型はintだけじゃないわけで,
#codehighlight(linenumber, cpp){{
double my_abs(double n){ return n &gt; 0 ? n : -n; }
}}
とかも要るだろうし, 他にもまだまだあるんじゃないかという感じである.~
こういうのを解決したのがテンプレート.

**テンプレート関数
上の例だと,
#codehighlight(linenumber, cpp){{
template&lt;class T&gt; T my_abs(T n){ return n &gt; 0 ? n : -n; }
}}

で, &#039;&#039;my_abs(-1.5)&#039;&#039; とかやると, Tにdoubleが代入されたやつが実行される.~
&#039;&#039;template&lt;class T&gt;&#039;&#039; でなく, &#039;&#039;template&lt;typename T&gt;&#039;&#039; でもよい.
#codehighlight(linenumber, cpp){{
template&lt;typename T, typename U&gt; U add(T a, T b){
  U au = a, bu = b;
  return au + bu;
}
}}
みたいに, 複数の型を使ったりしてもよい.~
明示的には, &#039;&#039;add&lt;int, long&gt;(1, 2)&#039;&#039; とかで呼び出す.~


**テンプレートクラス
例えば二次元ベクトルを扱いたいけど, 要素が整数なのか実数なのかは後で決めたいみたいな.
#codehighlight(linenumber, cpp){{
&lt;class T&gt;
class Vec{
    T x, y;
    Vec(T xx, T yy){ x = xx; y = yy; }
    Vec add(Vec other){
        return Vec(x + other.x, y + other.y);
    }
};
int main(void){
    Vec&lt;int&gt; a(0, 1), b(1, 0);
    Vec&lt;int&gt; c = a.add(b);
}
}}
みたいな感じで使う.~
注意すべきなのは,
#codehighlight(linenumber, cpp){{
Vec&lt;Vec&lt;int&gt;&gt; matrix;
}}
とかやると, &#039;&#039;Vec&lt;Vec&lt;int&gt;&gt;&#039;&#039; の &#039;&#039;&gt;&gt;&#039;&#039; を右シフトとして捉えてしまい, コンパイルエラーが起きる事.
#codehighlight(linenumber, cpp){{
Vec&lt;Vec&lt;int&gt; &gt; matrix;
}}
と, スペースを開けましょう.



*リンク
**Programming Place
[[ここ&gt;http://www.geocities.jp/ky_webid/index_old.html]].~
&#039;&#039;C++ hoge&#039;&#039; 的なググり方をするとよく引っかかるサイト.~
**C++マニアック
[[ここ&gt;http://homepage2.nifty.com/well/Index.html]].~
演算子の再定義ってどうやるんだっけとか, 何を再定義できるんだっけとか, ちょっとマニアックなのが載ってる.
**C/C++リファレンス
[[ここ&gt;http://www.cppll.jp/cppreference/index.html]].~
関数名が思い出せない時とか便利.
**cplusplus.com
[[ここ&gt;http://www.cplusplus.com/reference/]].~
詳しい. 便利.

&amp;link_edit()    </description>
    <dc:date>2013-03-27T16:44:29+09:00</dc:date>
    <utime>1364370269</utime>
  </item>
    <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] == bck){
            set&lt;P&gt; tmp = coloring(in, npos, color);
            res.insert(all(tmp));
        }
    }
    return res;
}
bool is_maxsnake(vvi &amp;in, set&lt;P&gt; &amp;body){
    // 蛇かチェックし, 頭/尻尾を決める.
    vector&lt;P&gt; heads;
    foreach(it, body){
        int cnt = 0;
        rep(dir, 4) if(body.count(*it + dirs[dir])) ++cnt;
        if(cnt &gt; 2) return false;
        if(cnt &lt; 2) heads.pb(*it);
    }
    if(sz(heads) &gt;= 3 || sz(heads) == 0) return false;

    // 蛇が最大であるかチェックする.
    repsz(i, heads) rep(dir, 4){
        P nei = heads[i] + dirs[dir];
        if(in[nei.X][nei.Y] == 0){
            int cnt = 0;
            rep(dir2, 4)
                if(in[(nei+dirs[dir2]).X][(nei+dirs[dir2]).Y] &gt; 0) ++cnt;
            if(cnt == 1) return false;
        }
    }
    return true;
}
/*
void output(const vvi &amp;in){
    repsz(i, in){
        repsz(j, in[i]){
            cout &lt;&lt; setw(3) &lt;&lt; in[i][j];
        }
        cout &lt;&lt; endl;
    }
    cout &lt;&lt; endl;
}
*/
bool solve(){
    int h, w;
    cin &gt;&gt; h &gt;&gt; w;
    if(!(h|w)) return false;

    // 周りは -1 で囲う.
    vvi in(h+2, vi(w+2, -1));
    rep(i, h) rep(j, w){
        char c; cin &gt;&gt; c;
        in[i+1][j+1] = c - &#039;0&#039;;
    }
    h += 2; w += 2;

    int color = 2;
    vector&lt;set&lt;P&gt; &gt; connects;
    rep(i, h) rep(j, w) if(in[i][j] == 1){
        connects.pb(coloring(in, P(i, j), color++));
    }

    // output(in);
    int res = 0;
    repsz(i, connects) if(is_maxsnake(in, connects[i])) ++res;
    cout &lt;&lt; res &lt;&lt; endl;
    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </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/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);
        }
    }
    int res = INF;
    rep(i, 8) mineq(res, dp[(1&lt;&lt;k)-1][i]);
    cout &lt;&lt; res &lt;&lt; endl;

    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </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;
            if(c == &#039;S&#039;) statue.insert(P(i, j));
        }
    }

    vector&lt;vvi&gt; dp(40);
    repsz(i, dp) dp[i] = vvi(8, vi(8));
    dp[0][7][0] = 1;
    rep(turn, sz(dp)-1){
        rep(i, 8) rep(j, 8) if(dp[turn][i][j]){
            rep(dir, 9){
                P np = P(i, j) + dirs[dir];
                if(!inBoard(np)) continue;
                if(statue.count(np - P(turn, 0))) continue;
                if(statue.count(np - P(turn+1, 0))) continue;
                dp[turn+1][np.X][np.Y] = 1;
            }
        }
    }
    if(dp[sz(dp)-1][0][7]){
        cout &lt;&lt; &quot;WIN&quot; &lt;&lt; endl;
    }else{
        cout &lt;&lt; &quot;LOSE&quot; &lt;&lt; endl;
    }
    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </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/147.html">
    <title>全体公開/合同練習会/20130323/A 温度検査</title>
    <link>https://w.atwiki.jp/mi_sawa/pages/147.html</link>
    <description>
      *問題の概要
気温を毎分1回測定した記録がある.
測定は100%信頼出来るものではなく, -273度未満, 又は, $$\pm 2$$ 分に $$\pm 2$$ 度以下の差の物が無い測定結果は, 無効とする.
有効な測定結果の平均を求めよ. 1つもない場合は, -300.0 を出力せよ.

**実装の方針, 注意点
#region()
最初の2つ, 最後の2つのデータは, $$\pm 2$$ 分のデータが他に比べて少ない.
処理を煩雑にしないため, 最初に2つ, 最後に2つの番兵を入れておく.
入力は整数であるが, 出力は実数である事に注意.
#endregion

*ソースコード
#region(close)
#codehighlight(linenumber,cpp){{{{{{
bool solve(){
    cout.setf(ios::fixed); cout.precision(10);
    int n;
    cin &gt;&gt; n;
    if(!n) return false;

    // 入力の左右に-INFな番兵を2つずつ置いておく.
    vector&lt;int&gt; in(n+4, -INF);
    rep(i, n) cin &gt;&gt; in[i+2];

    int sum = 0, cnt = 0;
    REP(i, 2, n+2){
        bool ok = false;
        REP(d, -2, 3) if(d &amp;&amp; abs(in[i+d] - in[i]) &lt;= 2) ok = true;
        if(in[i] &lt; -273) ok = false;
        if(ok){
            sum += in[i];
            ++cnt;
        }
    }
    if(cnt) cout &lt;&lt; (double)sum / cnt &lt;&lt; endl;
    else    cout &lt;&lt; &quot;-300.0&quot; &lt;&lt; endl;

    return true;
}
}}}}}}
#endregion

&amp;link_edit()

----
#pcomment(reply)    </description>
    <dc:date>2013-03-27T00:19:02+09:00</dc:date>
    <utime>1364311142</utime>
  </item>
  </rdf:RDF>
