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


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1150&lang=jp

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
#define mp make_pair
#define pb push_back
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 100000009
#define N 20005
using namespace std;

typedef pair<int, int> PI; // cost to;

int map[65][35];
int w, h;

bool checkin(int i, int j) {
  if (i >= 0 && j >= 0 && i < h && j < w && map[i][j] != INF) {
    return true;
  } else {
    return false;
  }
}
int retc(int i, int j) {
  if (map[i][j] == -1) {
    return 0;
  } else {
    return map[i][j];
  }
}

int make(int foot, int state, int i, int j) {
  return foot * w * h * 9 + state * w * h + i * w + j;
}

int main() {
  int cango[9][2]; // where right is from left,yx
  int hoge = 0;
  for (int y = 0; y <= 2; y++) {
    for (int x = 1; x <= 3 - abs(y); x++) {
      cango[hoge][0] = y;
      cango[hoge++][1] = x;
    }
  }
  for (int y = -2; y <= -1; y++) {
    for (int x = 1; x <= 3 - abs(y); x++) {
      cango[hoge][0] = y;
      cango[hoge++][1] = x;
    }
  }
  while (1) {
    vector<PI> G[3600 * 9 + 5]; // 0???????¶? 1???????¶? to,cost
    bool flag[3600 * 9 + 5];
    bool goal[3600 * 9 + 5];
    rep(i, 3600 * 9 + 5) {
      flag[i] = 0;
      goal[i] = 0;
    }
    cin >> w >> h;
    if (w == 0) {
      return 0;
    }
    char c;
    rep(i, h) {
      rep(j, w) {
        cin >> c;
        if (c == 'S')
          map[i][j] = 0;
        else if (c == 'T')
          map[i][j] = -1;
        else if (c == 'X')
          map[i][j] = INF;
        else
          map[i][j] = c - '0';
      }
    }
    rep(i, h) {
      rep(j, w) {
        if (!checkin(i, j))
          continue;
        rep(state1, 9) {
          int y = i + cango[state1][0], x = j + cango[state1][1];
          if (!checkin(y, x))
            continue;
          if (map[i][j] == -1 || map[y][x] == -1) {
            goal[make(0, state1, i, j)] = true;
            goal[make(1, state1, i, j)] = true;
          }
          rep(state2, 9) {
            if (state1 == state2)
              continue;
            int ny = i + cango[state2][0], nx = j + cango[state2][1];
            if (checkin(ny, nx)) {
              G[make(0, state1, i, j)].pb(
                  mp(make(1, state2, i, j), retc(ny, nx)));
            }
            ny = y - cango[state2][0], nx = x - cango[state2][1];
            if (checkin(ny, nx)) {
              G[make(1, state1, i, j)].pb(
                  mp(make(0, state2, ny, nx), retc(ny, nx)));
            }
          }
        }
      }
    }
    //        rep(i,3600*9+5){
    //            if(!G[i].empty()){
    //                rep(j,G[i].size()){
    //                    cout<<"from:"<< " foot:" <<i/(w*h*9) <<"
    //                    state:"<<i/w/h%9<<" i j:("<< i/w%h<< " "<<i%w<<
    //                    ")"<<endl;
    //
    //                    cout<<"to  :"<< " foot:" <<G[i][j].first/(w*h*9) <<"
    //                    state:"<<G[i][j].first/w/h%9<<" i j:("<<
    //                    G[i][j].first/w%h<< " "<<G[i][j].first%w <<")
    //                    cost:"<<G[i][j].second<<endl<<endl;
    //                }
    //            }
    //        }
    priority_queue<PI, vector<PI>, greater<PI>> pq;
    rep(j, w) {
      if (map[h - 1][j] != 0) {
        continue;
      }
      rep(st, 9) {
        int y = h - 1 + cango[st][0], x = j + cango[st][1];
        if (checkin(y, x)) {
          pq.push(mp(retc(y, x), (make(1, st, h - 1, j))));
        }
        y = h - 1 - cango[st][0], x = j - cango[st][1];
        if (checkin(y, x)) {
          pq.push(mp(retc(y, x), (make(0, st, y, x))));
        }
      }
    }
    int ans = -1;
    while (!pq.empty()) {
      PI now = pq.top();
      int cost = now.first;
      int from = now.second;
      pq.pop();
      if (flag[from]) {
        continue;
      }
      flag[from] = true;
      if (goal[from]) {
        ans = cost;
        break;
      }
      rep(i, G[from].size()) {
        if (!flag[G[from][i].first])
          pq.push(mp(G[from][i].second + cost, G[from][i].first));
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:


// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1150&lang=jp

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <vector>
#define mp make_pair
#define pb push_back
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 100000009
#define N 20005
using namespace std;

typedef pair<int, int> PI; // cost to;

int map[65][35];
int w, h;

bool checkin(int i, int j) {
  if (i >= 0 && j >= 0 && i < h && j < w && map[i][j] != INF) {
    return true;
  } else {
    return false;
  }
}
int retc(int i, int j) {
  if (map[i][j] == -1) {
    return 0;
  } else {
    return map[i][j];
  }
}

int make(int foot, int state, int i, int j) {
  return foot * w * h * 9 + state * w * h + i * w + j;
}

int main() {
  int cango[9][2]; // where right is from left,yx
  int hoge = 0;
  for (int y = 0; y <= 2; y++) {
    for (int x = 1; x <= 3 - abs(y); x++) {
      cango[hoge][0] = y;
      cango[hoge++][1] = x;
    }
  }
  for (int y = -2; y <= -1; y++) {
    for (int x = 1; x <= 3 - abs(y); x++) {
      cango[hoge][0] = y;
      cango[hoge++][1] = x;
    }
  }
  while (1) {
    vector<PI> G[3600 * 9 + 5]; // 0???????¶? 1???????¶? to,cost
    int dist[3600 * 9 + 5];
    bool goal[3600 * 9 + 5];
    rep(i, 3600 * 9 + 5) {
      dist[i] = INF;
      goal[i] = 0;
    }
    cin >> w >> h;
    if (w == 0) {
      return 0;
    }
    char c;
    rep(i, h) {
      rep(j, w) {
        cin >> c;
        if (c == 'S')
          map[i][j] = 0;
        else if (c == 'T')
          map[i][j] = -1;
        else if (c == 'X')
          map[i][j] = INF;
        else
          map[i][j] = c - '0';
      }
    }
    rep(i, h) {
      rep(j, w) {
        if (!checkin(i, j))
          continue;
        rep(state1, 9) {
          int y = i + cango[state1][0], x = j + cango[state1][1];
          if (!checkin(y, x))
            continue;
          if (map[i][j] == -1 || map[y][x] == -1) {
            goal[make(0, state1, i, j)] = true;
            goal[make(1, state1, i, j)] = true;
          }
          rep(state2, 9) {
            if (state1 == state2)
              continue;
            int ny = i + cango[state2][0], nx = j + cango[state2][1];
            if (checkin(ny, nx)) {
              G[make(0, state1, i, j)].pb(
                  mp(make(1, state2, i, j), retc(ny, nx)));
            }
            ny = y - cango[state2][0], nx = x - cango[state2][1];
            if (checkin(ny, nx)) {
              G[make(1, state1, i, j)].pb(
                  mp(make(0, state2, ny, nx), retc(ny, nx)));
            }
          }
        }
      }
    }
    //        rep(i,3600*9+5){
    //            if(!G[i].empty()){
    //                rep(j,G[i].size()){
    //                    cout<<"from:"<< " foot:" <<i/(w*h*9) <<"
    //                    state:"<<i/w/h%9<<" i j:("<< i/w%h<< " "<<i%w<<
    //                    ")"<<endl;
    //
    //                    cout<<"to  :"<< " foot:" <<G[i][j].first/(w*h*9) <<"
    //                    state:"<<G[i][j].first/w/h%9<<" i j:("<<
    //                    G[i][j].first/w%h<< " "<<G[i][j].first%w <<")
    //                    cost:"<<G[i][j].second<<endl<<endl;
    //                }
    //            }
    //        }
    priority_queue<PI, vector<PI>, greater<PI>> pq;
    rep(j, w) {
      if (map[h - 1][j] != 0) {
        continue;
      }
      rep(st, 9) {
        int y = h - 1 + cango[st][0], x = j + cango[st][1];
        if (checkin(y, x)) {
          pq.push(mp(retc(y, x), (make(1, st, h - 1, j))));
        }
        y = h - 1 - cango[st][0], x = j - cango[st][1];
        if (checkin(y, x)) {
          pq.push(mp(retc(y, x), (make(0, st, y, x))));
        }
      }
    }
    int ans = -1;
    while (!pq.empty()) {
      PI now = pq.top();
      int cost = now.first;
      int from = now.second;
      pq.pop();
      if (dist[from] < cost) {
        continue;
      }
      dist[from] = cost;
      if (goal[from]) {
        ans = cost;
        break;
      }
      rep(i, G[from].size()) {
        if (dist[G[from][i].first] > cost + G[from][i].second)
          pq.push(mp(G[from][i].second + cost, G[from][i].first));
      }
    }
    cout << ans << endl;
  }
  return 0;
}