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

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;

typedef vector<string> VS;
typedef pair<int, int> PII;
typedef set<PII> Positions;
typedef pair<Positions, Positions> PPP;
typedef pair<PPP, PII> PVP;
typedef pair<int, PVP> Node;
typedef priority_queue<Node, vector<Node>, greater<Node>> Queue;
typedef set<PVP> Set;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};

int H, W;
bool O[11][11];

int solve(PPP initM, int sr, int sc, int gr, int gc) {
  Set S;
  Queue Q;
  Node start(0, PVP(initM, PII(sr, sc)));
  Q.push(start);

  while (!Q.empty()) {
    Node node = Q.top();
    Q.pop();

    int cost = node.first;
    Positions panels = node.second.first.first;
    Positions cons = node.second.first.second;
    int r = node.second.second.first;
    int c = node.second.second.second;

    if (r == gr && c == gc) {
      return cost;
    }

    for (int i = 0; i < 4; i++) {
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (nr < 0 || nr >= H || nc < 0 || nc >= W)
        continue;

      if (O[nr][nc]) {
        continue;
      } else if (panels.count(PII(nr, nc))) {
        continue;
      } else if (cons.count(PII(nr, nc))) {
        int nnr = nr;
        int nnc = nc;
        for (int j = 0;; j++) {
          nnr += dr[i];
          nnc += dc[i];
          if (O[nnr][nnc] || cons.count(PII(nnr, nnc))) {
            nnr -= dr[i];
            nnc -= dc[i];
            PPP nextM(panels, cons);
            nextM.second.erase(PII(nr, nc));
            nextM.second.insert(PII(nnr, nnc));
            Node nextnode(cost, PVP(nextM, PII(r, c)));
            if (S.find(nextnode.second) != S.end())
              break;
            S.insert(nextnode.second);
            Q.push(nextnode);
            break;
          } else if (panels.count(PII(nnr, nnc))) {
            PPP nextM(panels, cons);
            nextM.second.erase(PII(nr, nc));
            nextM.first.erase(PII(nnr, nnc));
            Node nextnode(cost, PVP(nextM, PII(r, c)));
            if (S.find(nextnode.second) != S.end())
              break;
            S.insert(nextnode.second);
            Q.push(nextnode);
            break;
          }
        }
      } else if (!O[nr][nc]) {
        int ncost = cost + 1;
        Node nextnode(ncost, PVP(PPP(panels, cons), PII(nr, nc)));
        if (S.find(nextnode.second) != S.end())
          continue;
        S.insert(nextnode.second);
        Q.push(nextnode);
      }
    }
  }

  return -1;
}

int main() {
  while (cin >> H >> W) {
    if (H == 0 && W == 0)
      break;

    VS lines(H);
    for (int i = 0; i < H; i++) {
      cin >> lines[i];
    }

    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        O[i][j] = false;
      }
    }

    Positions panels;
    Positions cons;
    int sr, sc;
    int gr, gc;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (lines[i][j] == '#') {
          O[i][j] = true;
        } else if (lines[i][j] == '@') {
          sr = i;
          sc = j;
        } else if (lines[i][j] == 'E') {
          gr = i;
          gc = j;
        } else if (lines[i][j] == 'w') {
          panels.insert(PII(i, j));
        } else if (lines[i][j] == 'c') {
          cons.insert(PII(i, j));
        }
      }
    }

    cout << solve(PPP(panels, cons), sr, sc, gr, gc) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>
using namespace std;

typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<VS, PII> PVP;
typedef pair<int, PVP> Node;
typedef priority_queue<Node, vector<Node>, greater<Node>> Queue;
typedef set<PVP> Set;
const int dr[4] = {0, 0, 1, -1};
const int dc[4] = {1, -1, 0, 0};

int H, W;

int solve(VS initM, int sr, int sc, int gr, int gc) {
  Set S;
  Queue Q;
  Node start(0, PVP(initM, PII(sr, sc)));
  Q.push(start);

  while (!Q.empty()) {
    Node node = Q.top();
    Q.pop();

    int cost = node.first;
    VS M = node.second.first;
    int r = node.second.second.first;
    int c = node.second.second.second;

    if (r == gr && c == gc) {
      return cost;
    }

    for (int i = 0; i < 4; i++) {
      int nr = r + dr[i];
      int nc = c + dc[i];
      if (nr < 0 || nr >= H || nc < 0 || nc >= W)
        continue;

      if (M[nr][nc] == '#') {
        continue;
      } else if (M[nr][nc] == 'w') {
        continue;
      } else if (M[nr][nc] == 'c') {
        int nnr = nr;
        int nnc = nc;
        for (int j = 0;; j++) {
          nnr += dr[i];
          nnc += dc[i];
          if (M[nnr][nnc] == '#' || M[nnr][nnc] == 'c') {
            nnr -= dr[i];
            nnc -= dc[i];
            VS nextM = M;
            nextM[nr][nc] = '.';
            nextM[nnr][nnc] = 'c';
            Node nextnode(cost, PVP(nextM, PII(r, c)));
            if (S.find(nextnode.second) != S.end())
              break;
            S.insert(nextnode.second);
            Q.push(nextnode);
            break;
          } else if (M[nnr][nnc] == 'w') {
            VS nextM = M;
            nextM[nr][nc] = '.';
            nextM[nnr][nnc] = '.';
            Node nextnode(cost, PVP(nextM, PII(r, c)));
            if (S.find(nextnode.second) != S.end())
              break;
            S.insert(nextnode.second);
            Q.push(nextnode);
            break;
          }
        }
      } else if (M[nr][nc] == '.') {
        int ncost = cost + 1;
        Node nextnode(ncost, PVP(M, PII(nr, nc)));
        if (S.find(nextnode.second) != S.end())
          continue;
        S.insert(nextnode.second);
        Q.push(nextnode);
      }
    }
  }

  return -1;
}

int main() {
  while (cin >> H >> W) {
    if (H == 0 && W == 0)
      break;

    VS lines(H);
    for (int i = 0; i < H; i++) {
      cin >> lines[i];
    }

    VS M = lines;
    int sr, sc;
    int gr, gc;
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (M[i][j] == '@') {
          M[i][j] = '.';
          sr = i;
          sc = j;
        } else if (M[i][j] == 'E') {
          M[i][j] = '.';
          gr = i;
          gc = j;
        }
      }
    }

    cout << solve(M, sr, sc, gr, gc) << endl;
  }
}