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

/*
 * AOJ 2212: Stolen Jewel
 * ???????????°?????????????????°??°???????????¨?????¨???????????????????????¨???????????¶?????????????????¢?????????????????¨???????????????????????¢????¬????????????¶????±???°????????????????°???\\??°???
 * ?±???????DP+?????????
 * ??????????????¢?§???????????????????????????¶???????¢??????????????????¨??¶???i????????????????????????????¬???¬?§???°?????????????????¶???j???d[x][y][i]??¨??????(x,y)??¨?????????i???????°???\\??°?????¨Dijkstra?????°??°????????????????????????
 */

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

using namespace std;

int m, n, nr, ns;
string mat[53];
string rule[13];

int d[53][53][113];
int t[113][4];
string suf[113];

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
char dc[] = {'U', 'R', 'D', 'L'};

struct Status {
  int x, y, s, d;

  Status() {}

  Status(int dd, int xx, int yy, int ss) : d(dd), x(xx), y(yy), s(ss) {}

  void Get(int &dd, int &xx, int &yy, int &ss) const {
    dd = d;
    xx = x;
    yy = y;
    ss = s;
  }

  bool operator<(const Status &ts) const { return d > ts.d; }
};

priority_queue<Status> pq;

int Dijkstra() {
  while (!pq.empty())
    pq.pop();
  memset(d, 0x3f, sizeof(d));
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < n; ++j) {
      if (mat[i][j] == 'S') {
        d[i][j][0] = 0;
        pq.emplace(0, i, j, 0);
        goto L;
      }
    }
  }
L:
  int ans = -1;
  while (!pq.empty()) {
    int pre, x, y, s;
    pq.top().Get(pre, x, y, s);
    pq.pop();
    if (pre > d[x][y][s])
      continue;
    for (int k = 0; k < 4; ++k) {
      int xx, yy, ss;
      ss = t[s][k];
      if (ss == -1)
        continue;
      xx = x + dx[k];
      yy = y + dy[k];

      if (xx >= 0 && xx < m && yy >= 0 && yy < n && mat[xx][yy] != '#' &&
          pre + 1 < d[xx][yy][ss]) {
        if (mat[xx][yy] == 'G') {
          ans = pre + 1;
          return ans;
        }
        d[xx][yy][ss] = pre + 1;
        pq.emplace(pre + 1, xx, yy, ss);
      }
    }
  }
  return ans;
}

bool IsSuf(string a, string b) {
  if (a.length() < b.length())
    return false;
  return a.substr(a.length() - b.length()) == b;
}

void GaoEdge() {
  sort(suf, suf + ns);
  memset(t, 0, sizeof(t));
  for (int i = 0; i < ns; ++i) {
    for (int k = 0; k < 4; ++k) {
      string ts = suf[i] + dc[k];
      for (int j = 0; j < nr; ++j) {
        if (IsSuf(ts, rule[j])) {
          t[i][k] = -1;
          break;
        }
      }
      if (t[i][k] != -1) {
        for (int j = 0; j < ns; ++j) {
          if (IsSuf(ts, suf[j]) && suf[j].length() > suf[t[i][k]].length()) {
            t[i][k] = j;
          }
        }
      }
    }
  }
}

int main() {
  // freopen("/Users/yogy/acm-challenge-workbook/db.in", "r", stdin);
  while (cin >> m >> n && m > 0 && n > 0) {
    for (int i = 0; i < m; ++i) {
      cin >> mat[i];
    }
    cin >> nr;
    ns = 0;
    suf[ns++] = "";
    for (int i = 0; i < nr; ++i) {
      cin >> rule[i];
      for (int j = 1; j < rule[i].length(); ++j) {
        suf[ns++] = rule[i].substr(0, j);
      }
    }
    GaoEdge();
    int ans = Dijkstra();
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

/*
 * AOJ 2212: Stolen Jewel
 * ???????????°?????????????????°??°???????????¨?????¨???????????????????????¨???????????¶?????????????????¢?????????????????¨???????????????????????¢????¬????????????¶????±???°????????????????°???\\??°???
 * ?±???????DP+?????????
 * ??????????????¢?§???????????????????????????¶???????¢??????????????????¨??¶???i????????????????????????????¬???¬?§???°?????????????????¶???j???d[x][y][i]??¨??????(x,y)??¨?????????i???????°???\\??°?????¨Dijkstra?????°??°????????????????????????
 */

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

using namespace std;

int m, n, nr, ns;
string mat[53];
string rule[13];

int d[53][53][113];
int t[113][4];
string suf[113];

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
char dc[] = {'U', 'R', 'D', 'L'};

struct Status {
  int x, y, s, d;

  Status() {}

  Status(int dd, int xx, int yy, int ss) : d(dd), x(xx), y(yy), s(ss) {}

  void Get(int &dd, int &xx, int &yy, int &ss) const {
    dd = d;
    xx = x;
    yy = y;
    ss = s;
  }

  bool operator<(const Status &ts) const { return d > ts.d; }
};

priority_queue<Status> pq;

int Dijkstra() {
  while (!pq.empty())
    pq.pop();
  memset(d, 0x3f, sizeof(d));
  for (int i = 0; i < m; ++i) {
    for (int j = 0; j < n; ++j) {
      if (mat[i][j] == 'S') {
        d[i][j][0] = 0;
        pq.emplace(0, i, j, 0);
        goto L;
      }
    }
  }
L:
  int ans = -1;
  while (!pq.empty()) {
    int pre, x, y, s;
    pq.top().Get(pre, x, y, s);
    pq.pop();
    if (pre > d[x][y][s])
      continue;

    //    cout << "pre: " << x << " " << y << " " << pre << endl;
    for (int k = 0; k < 4; ++k) {
      int xx, yy, ss;
      ss = t[s][k];
      //      cout <<"s=" << suf[s] << " , ss = " << suf[ss] << endl;
      if (ss == -1)
        continue;
      xx = x + dx[k];
      yy = y + dy[k];
      //      if (x == 4 && y == 7) cout << xx << yy << mat[xx][yy] << endl;

      if (xx >= 0 && xx < m && yy >= 0 && yy < n && mat[xx][yy] != '#' &&
          pre + 1 < d[xx][yy][ss]) {
        d[xx][yy][ss] = pre + 1;
        pq.emplace(pre + 1, xx, yy, ss);
      }
    }
  }
  while (1)
    ;
  return ans;
}

bool IsSuf(string a, string b) {
  if (a.length() < b.length())
    return false;
  return a.substr(a.length() - b.length()) == b;
}

void GaoEdge() {
  sort(suf, suf + ns);
  memset(t, 0, sizeof(t));
  for (int i = 0; i < ns; ++i) {
    for (int k = 0; k < 4; ++k) {
      string ts = suf[i] + dc[k];
      for (int j = 0; j < nr; ++j) {
        if (IsSuf(ts, rule[j])) {
          t[i][k] = -1;
          break;
        }
      }
      if (t[i][k] != -1) {
        for (int j = 0; j < ns; ++j) {
          if (IsSuf(ts, suf[j]) && suf[j].length() > suf[t[i][k]].length()) {
            t[i][k] = j;
          }
        }
      }
    }
  }
}

int main() {
  // freopen("/Users/yogy/acm-challenge-workbook/db.in", "r", stdin);
  while (cin >> m >> n && m > 0 && n > 0) {
    for (int i = 0; i < m; ++i) {
      cin >> mat[i];
    }
    cin >> nr;
    ns = 0;
    suf[ns++] = "";
    for (int i = 0; i < nr; ++i) {
      cin >> rule[i];
      for (int j = 1; j < rule[i].length(); ++j) {
        suf[ns++] = rule[i].substr(0, j);
      }
    }
    GaoEdge();
    int ans = Dijkstra();
    cout << ans << endl;
  }
  return 0;
}