Problem p00725 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>

using namespace std;

const int WALL = 100;

struct Data {
  char field[22][22];
  char x, y;
  char step;
  bool operator<(const Data &a) const {
    return (0 < memcmp(field, a.field, sizeof(field)));
  }
};

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int main(void) {
  int h, w, cnt = 0;
  int start[2];
  char f[22][22];
  while (cin >> w >> h) {
    cnt++;
    if (h == 0 && w == 0) {
      break;
    }
    for (int i = 0; i < 22; i++) {
      for (int j = 0; j < 22; j++) {
        f[i][j] = WALL;
      }
    }

    for (int i = 1; i <= h; i++) {
      for (int j = 1; j <= w; j++) {
        int v;
        scanf("%d", &v);
        f[i][j] = v;
        if (v == 2) {
          start[0] = i, start[1] = j;
          f[i][j] = 0;
        }
      }
    }

    queue<Data> q;
    Data d;
    memcpy(d.field, f, sizeof(f));
    d.step = 0;
    d.x = start[1], d.y = start[0];
    for (q.push(d); !q.empty(); q.pop()) {
      Data &data2 = q.front();
      // if (vis.count(data2)) continue;
      // vis.insert(data2);

      // if (cnt == 21){
      // 	cerr << endl;
      // 	for (int i = 1; i <= h; i++){
      // 		for (int j = 1; j <= w; j++){
      // 			if (i == data2.y && j == data2.x){
      // 				cerr << "* ";
      // 			}
      // 			else {
      // 				cerr << (int)data2.field[i][j] << " ";
      // 			}
      // 		}
      // 		cerr << endl;
      // 	}
      // 	cin >> ddd;
      // }

      if (data2.step + 1 > 10) {
        continue;
      }
      for (int i = 0; i < 4; i++) {
        Data data = data2;
        int ny = data.y, nx = data.x;
        if (data.field[ny + dy[i]][nx + dx[i]] == 1) {
          continue;
        }
        while (1) {
          ny += dy[i], nx += dx[i];
          if (data.step + 1 <= 10 && data.field[ny][nx] == 3) {
            // goal
            cout << data.step + 1 << endl;
            goto GOAL;
          }
          if (data.field[ny][nx] == WALL) {
            // fault
            break;
          }
          if (data.field[ny][nx] == 1) {
            // wall
            data.field[ny][nx] = 0;
            data.y = ny - dy[i], data.x = nx - dx[i];
            data.step++;
            q.push(data);
            break;
          }
        }
      }
    }
    // cout << "size " << q.size() << endl;
    cout << -1 << endl;
  GOAL:;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>

using namespace std;

const int WALL = 100;

struct Data {
  char field[22][22];
  char x, y;
  char step;
  bool operator<(const Data &a) const {
    return (0 < memcmp(field, a.field, sizeof(field)));
  }
};

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};

int main(void) {
  int h, w, cnt = 0;
  int start[2];
  char f[22][22];
  while (cin >> w >> h) {
    cnt++;
    if (h == 0 && w == 0) {
      break;
    }
    for (int i = 0; i < 22; i++) {
      for (int j = 0; j < 22; j++) {
        f[i][j] = WALL;
      }
    }

    for (int i = 1; i <= h; i++) {
      for (int j = 1; j <= w; j++) {
        int v;
        scanf("%d", &v);
        f[i][j] = v;
        if (v == 2) {
          start[0] = i, start[1] = j;
          f[i][j] = 0;
        }
      }
    }

    queue<Data> q;
    set<Data> vis;
    Data d;
    memcpy(d.field, f, sizeof(f));
    d.step = 0;
    d.x = start[1], d.y = start[0];
    for (q.push(d); !q.empty();) {
      queue<Data> nq;
      for (; !q.empty(); q.pop()) {
        Data &data2 = q.front();
        // if (vis.count(data2)) continue;
        // vis.insert(data2);

        // if (cnt == 21){
        // 	cerr << endl;
        // 	for (int i = 1; i <= h; i++){
        // 		for (int j = 1; j <= w; j++){
        // 			if (i == data2.y && j == data2.x){
        // 				cerr << "* ";
        // 			}
        // 			else {
        // 				cerr << (int)data2.field[i][j] << " ";
        // 			}
        // 		}
        // 		cerr << endl;
        // 	}
        // 	cin >> ddd;
        // }

        if (data2.step + 1 > 10) {
          continue;
        }
        for (int i = 0; i < 4; i++) {
          Data data = data2;
          int ny = data.y, nx = data.x;
          if (data.field[ny + dy[i]][nx + dx[i]] == 1) {
            continue;
          }
          while (1) {
            ny += dy[i], nx += dx[i];
            if (data.step + 1 <= 10 && data.field[ny][nx] == 3) {
              // goal
              cout << data.step + 1 << endl;
              goto GOAL;
            }
            if (data.field[ny][nx] == WALL) {
              // fault
              break;
            }
            if (data.field[ny][nx] == 1) {
              // wall
              data.field[ny][nx] = 0;
              data.y = ny - dy[i], data.x = nx - dx[i];
              data.step++;
              nq.push(data);
              break;
            }
          }
        }
      }
      swap(q, nq);
      // cout << "size " << q.size() << endl;
    }
    cout << -1 << endl;
  GOAL:;
  }
  return 0;
}