Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

Alternate Escape

アリスハウス

AliceとBobはボードゲームで遊んでいる．
このボードゲームは， H 行 W 列のマス目が書かれた盤面と1つのコマを使って遊ぶ．
このゲームでは，盤面の左上のマスを1行1列目として，下方向に行を，右方向に列を数える．

マス同士が隣接する辺と，マスが盤面の外側と接する辺には壁を置けるようになっていて，ゲームの開始時にはそれぞれの辺について壁の有無が指定されている．また，ゲームの開始時には，コマが盤面のマスのいずれか1箇所に置かれている．

AliceとBobは交互に手番をこなすことでゲームを進める．
ゲームはAliceの手番から始まる．
Aliceの目的は，コマを盤面の外まで動かして，迷路から脱出させることである．
Aliceが1手でできる行動は，コマを今ある位置のマスから，上下左右に隣接するマスのうち，間の辺に壁がない方向のいずれかに移動させることである．
コマの今あるマスが盤面の外側に接していて，間の辺に壁がない場合，そこからコマを脱出させることができる．

一方，Bobの目的は，コマの脱出を妨害することである．
Bobの手番では，壁の有無を反転させるか，何もせずに手番を終えるかを選ぶことができる．
壁の有無を反転させることを選んだ場合，盤面のすべてのマスの辺について，壁の有無が反転する．

盤面の初期状態と，コマの初期位置が与えられるので，AliceとBobの両者が最適な行動をとったときに，Aliceがコマを盤面から脱出させられるか判定せよ．
ただし，Aliceの手番においてコマが4方向とも壁で囲まれてしまった場合は脱出できないとみなす．

Input

入力は40個以下のデータセットからなる．
それぞれのデータセットは次の形式で与えられる．

H W R C
 Horz1,1 Horz1,2 ... Horz1,W
Vert1,1 Vert1,2 ... Vert1,W+1
...
VertH,1 VertH,2 ... VertH,W+1
 HorzH+1,1 HorzH+1,2 ... HorzH+1,W

1行目には4つの整数 H, W (1 ≤ H, W ≤ 500), R, C (1 ≤ R ≤ H, 1 ≤ C ≤ W) が与えられる．
これらは盤面が H 行 W 列のマス目からなり，コマの初期位置が R 行 C 列目であることを表す．

続く 2H + 1 行には盤面の初期状態が与えられる．

2i 行目 (1 ≤ i ≤ H + 1) は，W個の整数 Horzi,1, Horzi,2, ..., Horzi,Wを含む．
Horzi,jは，i 行 j 列目のマスの上側の辺に壁が有るとき1で，無いとき0である．
ただし，HorzH+1,jは， H 行 j 列目のマスの下側の辺における壁の有無を表す．

2i + 1 行目 (1 ≤ i ≤ H) は，W + 1 個の整数 Verti,1, Verti,2, ..., Verti,W+1を含む．
Verti,jは， i 行 j 列目のマスの左側の辺に壁が有るとき1で，無いとき0である．
ただし，Verti,W+1は， i 行 W 列目のマスの右側の辺における壁の有無を表す．

入力の終わりは，4つのゼロからなる1行で示される．

Output

それぞれのデータセットについて，Aliceがコマを盤面から脱出させられる場合は"Yes"，できない場合は"No"と1行に出力せよ．

Sample Input

3 3 2 2
1 1 1
0 0 0 0
1 1 1
0 0 0 0
1 1 1
0 0 0 0
1 1 1
3 3 2 2
1 0 1
1 0 1 1
1 0 0
0 0 0 0
0 0 1
1 1 0 1
1 0 1
1 3 1 1
1 1 1
1 0 0 1
1 0 1
2 2 1 1
1 0
1 0 0
0 0
0 0 0
0 0
0 0 0 0

Output for Sample Input

Yes
No
Yes
No

Hint

1つ目のデータセットではAliceは次のように動くことでコマを脱出させられる。

初期状態

Aliceがコマを左に動かす

Bobは脱出を阻止するために壁を反転させる

Aliceがコマを上に動かす

Bobが次の手番で壁の有無を反転させてもさせなくても、
Aliceは次の手番でコマを脱出させられる。

Solution in C++11 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;

#define DUMP(x) cerr << #x << "=" << x << endl
#define DUMP2(x, y) cerr<<"("<<#x<<", "<<#y<<") = ("<<x<<", "<<y<<")"<< endl
#define BINARY(x) static_cast<bitset<16> >(x)

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,m,n) for (int i=m;i<(int)(n);i++)

#define in_range(x, y, w, h) (0<=(int)(x) && (int)(x)<(int)(w) && 0<=(int)(y) && (int)(y)<(int)(h))
#define ALL(a) (a).begin(),(a).end()

typedef long long ll;
const int INF = 1e9;
typedef pair<int, int> PII;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, -1, 0, 1};

int main()
{
    int H, W, R, C;
    while (cin >> H >> W >> R >> C, H || W || R || C) {
        int wall[510][510][4] = {};
        bool is_winning[510][510] = {};

        for (int i=0; i<=H; i++) {
            for (int x=1; x<=W; x++) {
                int t; cin >> t;
                wall[i][x][3] = t;
                wall[i+1][x][1] = t;
            }
            if (i == H) break;
            for (int x=0; x<=W; x++) {
                int t; cin >> t;
                wall[i+1][x][0] = t;
                wall[i+1][x+1][2] = t;
            }
        }

        /**
        for (int y=1; y<=H; y++) {
            for (int x=1; x<=W; x++) {
                cerr << "(" << x << ", " << y << ") : ";
                rep(i, 4) cerr << wall[y][x][i] << " ";
                cerr << endl;
            }
        }
        **/

        for (int i=0; i<W+2; i++) {
            is_winning[0][i] = is_winning[H+1][i] = true;
        }
        for (int i=0; i<H+2; i++) {
            is_winning[i][0] = is_winning[i][W+1] = true;
        }

        /**
        cerr << "-----------------" << endl;
        rep(y, H+2) {
            rep(x, W+2) {
                cerr << is_winning[y][x] << " ";
            }
            cerr << endl;
        }
        **/

        queue<PII> Q;
        for (int i=1; i<=W; i++) {
            Q.emplace(i, 1);
            Q.emplace(i, H);
        }
        for (int i=1; i<=H; i++) {
            Q.emplace(1, i);
            Q.emplace(W, i);
        }

        while (Q.size()) {
            PII p = Q.front(); Q.pop();
            int x = p.first, y = p.second;

            bool ok1 = false, ok2 = false;
            rep(i, 4) {
                int nx = x+dx[i], ny = y+dy[i];
                assert(wall[y][x][i] == wall[ny][nx][(i+2)%4]);
                if (wall[y][x][i] == 0) {
                    ok1 |= is_winning[ny][nx];
                } else {
                    ok2 |= is_winning[ny][nx];
                }
            }

            if (ok1 && ok2) {
                is_winning[y][x] = true;
                rep(i, 4) {
                    int nx = x+dx[i], ny = y+dy[i];
                    if (!is_winning[ny][nx]) Q.emplace(nx, ny);
                }
            }

            /**
            cerr << "-----------------" << endl;
            rep(y, H+2) {
                rep(x, W+2) {
                    cerr << is_winning[y][x] << " ";
                }
                cerr << endl;
            }
            **/
        }

        bool ok = is_winning[R][C];
        rep(i, 4) {
            int nx = C + dx[i], ny = R + dy[i];
            if (wall[R][C][i] == 0) {
                ok |= is_winning[ny][nx];
            }
        }
        cout << (ok ? "Yes" : "No") << endl;
    }
}