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


#include <algorithm>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <utility>
#include <vector>

const int INF = 1 << 30;
using namespace std;
int solve();

int main(void) {

  // FILE *fpin = freopen("data.txt","r",stdin);

  solve();

  return 0;
}

int solve() {

  int N;
  cin >> N;

  vector<int> p(N + 1, 0);
  vector<int> ng(N + 1, 0);
  vector<int> ok(N + 1, 0);
  vector<int> cost(N + 1, INF);
  vector<int> visited(N + 1, 0);
  vector<int> doneNode(N + 1, 0);
  vector<int> contain(N + 1, 0);

  for (int i = 0; i < N; i++)
    cin >> p[i + 1];

  //?????????????????????
  for (int i = 1; i < N; i++) {

    int pos = i;
    if (p[i] == 0) {
      continue;
    }
    if (ng[i] != 0) {
      continue;
    }
    if (ok[i] != 0) {
      continue;
    }

    visited.clear();
    visited.resize(N + 1, 0);

    while (true) {

      if (p[pos] == 0) {
        for (int j = 1; j < N; j++) {
          if (visited[j])
            ok[j] = 1;
        }
        break;
      }

      if (visited[pos] != 0 || ng[pos] != 0) {

        for (int j = 1; j < N; j++) {
          if (visited[j]) {
            ng[j] = 1;
            visited[j] = 0;
          }
        }

        break;
      }

      visited[pos] = 1;
      pos += p[pos];
    }
  }

  priority_queue<int, vector<int>, greater<int>> q;
  q.push(1);
  cost[1] = 0;

  while (!q.empty()) {

    int cnode = q.top();
    contain[cnode] = 0;

    q.pop();
    doneNode[cnode] = 1;

    if (p[cnode] == 0) {

      for (int i = 1; i <= 6; i++) {

        int j = min(i + cnode, N);
        if (ng[j]) {
          continue;
        }

        if (cost[j] == INF || cost[cnode] + 1 < cost[j]) {
          cost[j] = cost[cnode] + 1;
          contain[j] = 1;
          q.push(j);
        }
      }

    } else {

      if (ng[cnode] == 0) {

        int j = min(cnode + p[cnode], N);

        if (cost[j] == INF || cost[cnode] < cost[j]) {
          cost[j] = cost[cnode];
          contain[j] = 1;
          q.push(j);
        }
      }
    }
  }

  cout << cost[N] << endl;
  return 0;
}

Error: TLE

Fixed submission:


#include <algorithm>
#include <ctime>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <utility>
#include <vector>

const int INF = 1 << 30;
using namespace std;
int solve();

int main(void) {

  //	int s = clock();
  //	FILE *fpin = freopen("data.txt","r",stdin);

  solve();
  /*
          int e = clock();
          cout << e - s << endl;
  */

  return 0;
}

int solve() {

  int N;
  cin >> N;

  vector<int> p(N + 1, 0);
  vector<int> ng(N + 1, 0);
  vector<int> dp(N + 1, INF);
  vector<int> visited(N + 1, 0);

  for (int i = 0; i < N; i++)
    cin >> p[i + 1];

  //?????????????????????
  for (int i = 1; i < N; i++) {

    int pos = i;
    if (p[i] == 0) {
      continue;
    }

    visited.clear();
    visited.resize(N + 1, 0);

    set<int> s;

    while (true) {

      if (p[pos] == 0) {
        break;
      }

      if (visited[pos] != 0 || ng[pos] != 0) {

        for (int j = 1; j < N; j++) {
          if (visited[j]) {
            ng[j] = 1;
          }
        }

        break;
      }

      visited[pos] = 1;
      pos += p[pos];
    }
  }

  // DP??¬???
  dp[1] = 0;
  for (int i = 1; i < N; i++) {

    if (p[i]) {
      continue;
    }

    int l = dp[i];

    for (int j = 1; j <= 6; j++) {

      int k = min(i + j, N);

      if (ng[k]) {
        continue;
      }

      dp[k] = min(dp[k], l + 1);

      stack<int> s; // s??????????????????????????????????????\\??????
      s.push(k);

      while (!s.empty()) {

        int r = s.top();
        s.pop();
        dp[r] = min(dp[r], l + 1);

        if (p[r] != 0) {
          s.push(r + p[r]);
        }
      }
    }
  }
  /*
  for( int i = 0; i < dp.size(); i++ ) {
          cout << i << ":" << p[i] << ":" << dp[i] << ":" << ng[i] << endl;
  }
  */
  cout << dp[N] << endl;

  return 0;
}