Problem p01271 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

typedef pair<char, char> P;

struct state {
  P p1, p2;
  state(P p1_, P p2_) {
    p1 = p1_;
    p2 = p2_;
  }
};
int w, h;
int dx1[4] = {0, -1, 1, 0};
int dy1[4] = {-1, 0, 0, 1};
int dx2[4] = {0, 1, -1, 0};
int dy2[4] = {-1, 0, 0, 1};
bool flag[51][51][51][51];
char L[51][51];
char R[51][51];

void init() {
  for (int i = 0; i < 51; i++) {
    for (int j = 0; j < 51; j++) {
      for (int k = 0; k < 51; k++) {
        for (int l = 0; l < 51; l++) {
          flag[i][j][k][l] = false;
        }
      }
    }
  }
}

// デバッグ用
void debug() {
  cout << "[Left]" << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << L[y][x];
    }
    cout << endl;
  }
  cout << endl;
  cout << "[right]" << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << R[y][x];
    }
    cout << endl;
  }
  cout << endl;
}

// R[y][x] == 'R' となる (x,y) を返す
P R_search() {
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (R[y][x] == 'R') {
        R[y][x] = '.';
        return P(x, y);
      }
    }
  }
  return P(0, 0);
}

// L[y][x] == 'L' となる (x,y) を返す
P L_search() {
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (L[y][x] == 'L') {
        L[y][x] = '.';
        return P(x, y);
      }
    }
  }
  return P(0, 0);
}

bool bfs() {
  P ls = L_search();
  P rs = R_search();

  queue<pair<P, P>> q;
  pair<P, P> s(ls, rs);
  q.push(s);

  while (!q.empty() && q.size() < 1000000) {
    pair<P, P> now = q.front();
    q.pop();
    int x1 = now.first.first;
    int y1 = now.first.second;
    int x2 = now.second.first;
    int y2 = now.second.second;

    if (L[y1][x1] == '%' && R[y2][x2] == '%') {
      return true;
    } else if (L[y1][x1] == '%' && R[y2][x2] != '%') {
      continue;
    } else if (L[y1][x1] != '%' && R[y2][x2] == '%') {
      continue;
    }
    flag[y1][x1][y2][x2] = true;

    for (int i = 0; i < 4; i++) {
      int mx1 = x1 + dx1[i];
      int my1 = y1 + dy1[i];
      if (mx1 < 0 || my1 < 0 || mx1 >= w || my1 >= h || L[my1][mx1] == '#') {
        mx1 = x1;
        my1 = y1;
      }
      int mx2 = x2 + dx2[i];
      int my2 = y2 + dy2[i];
      if (mx2 < 0 || my2 < 0 || mx2 >= w || my2 >= h || R[my2][mx2] == '#') {
        mx2 = x2;
        my2 = y2;
      }
      P p1(mx1, my1);
      P p2(mx2, my2);
      pair<P, P> next(p1, p2);
      if (!flag[my1][mx1][my2][mx2]) {
        q.push(next);
        flag[my1][mx1][my2][mx2] = true;
      }
    }
  }
  return false;
}

int main() {
  while (cin >> w >> h, w || h) {
    init();

    for (int y = 0; y < h; y++) {
      string l, r;
      cin >> l >> r;
      for (int x = 0; x < w; x++) {
        L[y][x] = l[x];
        R[y][x] = r[x];
      }
    }
    // debug();
    bool ans = bfs();
    if (ans)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;

typedef pair<char, char> P;

struct state {
  P p1, p2;
  state(P p1_, P p2_) {
    p1 = p1_;
    p2 = p2_;
  }
};
int w, h;
int dx1[4] = {0, -1, 1, 0};
int dy1[4] = {-1, 0, 0, 1};
int dx2[4] = {0, 1, -1, 0};
int dy2[4] = {-1, 0, 0, 1};
bool flag[51][51][51][51];
char L[51][51];
char R[51][51];

void init() {
  for (int i = 0; i < 51; i++) {
    for (int j = 0; j < 51; j++) {
      for (int k = 0; k < 51; k++) {
        for (int l = 0; l < 51; l++) {
          flag[i][j][k][l] = false;
        }
      }
    }
  }
}

// デバッグ用
void debug() {
  cout << "[Left]" << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << L[y][x];
    }
    cout << endl;
  }
  cout << endl;
  cout << "[right]" << endl;
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      cout << R[y][x];
    }
    cout << endl;
  }
  cout << endl;
}

// R[y][x] == 'R' となる (x,y) を返す
P R_search() {
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (R[y][x] == 'R') {
        R[y][x] = '.';
        return P(x, y);
      }
    }
  }
  return P(0, 0);
}

// L[y][x] == 'L' となる (x,y) を返す
P L_search() {
  for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {
      if (L[y][x] == 'L') {
        L[y][x] = '.';
        return P(x, y);
      }
    }
  }
  return P(0, 0);
}

bool bfs() {
  P ls = L_search();
  P rs = R_search();

  queue<pair<P, P>> q;
  pair<P, P> s(ls, rs);
  q.push(s);

  while (!q.empty() && q.size() < 5000000) {
    pair<P, P> now = q.front();
    q.pop();
    int x1 = now.first.first;
    int y1 = now.first.second;
    int x2 = now.second.first;
    int y2 = now.second.second;
    flag[y1][x1][y2][x2] = true;
    if (L[y1][x1] == '%' && R[y2][x2] == '%') {
      return true;
    }

    for (int i = 0; i < 4; i++) {
      int mx1 = x1 + dx1[i];
      int my1 = y1 + dy1[i];
      if (mx1 < 0 || my1 < 0 || mx1 >= w || my1 >= h || L[my1][mx1] == '#') {
        mx1 = x1;
        my1 = y1;
      }
      int mx2 = x2 + dx2[i];
      int my2 = y2 + dy2[i];
      if (mx2 < 0 || my2 < 0 || mx2 >= w || my2 >= h || R[my2][mx2] == '#') {
        mx2 = x2;
        my2 = y2;
      }
      P p1(mx1, my1);
      P p2(mx2, my2);
      pair<P, P> next(p1, p2);
      if (flag[my1][mx1][my2][mx2]) {
        continue;
      } else if (L[my1][mx1] == '%' && R[my2][mx2] != '%') {
        flag[my1][mx1][my2][mx2] = true;
      } else if (L[my1][mx1] != '%' && R[my2][mx2] == '%') {
        flag[my1][mx1][my2][mx2] = true;
      } else {
        q.push(next);
      }
    }
  }
  return false;
}

int main() {
  while (cin >> w >> h, w || h) {
    init();

    for (int y = 0; y < h; y++) {
      string l, r;
      cin >> l >> r;
      for (int x = 0; x < w; x++) {
        L[y][x] = l[x];
        R[y][x] = r[x];
      }
    }
    // debug();
    bool ans = bfs();
    if (ans)
      cout << "Yes" << endl;
    else
      cout << "No" << endl;
  }
}