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



// C言語

#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 10000

// 解法(分けた方が見やすいかなと思って関数にした)
int Answer(int N, vector<int> character) {
  int ans = 9999999;
  // 消す基準となる玉の位置
  for (int i = 0; i < N; i++) {
    // k : 変えた後の色
    for (int j = 1; j <= 3; j++) {

      // 色を変えたところで意味のない部分は考えない(悪いけどごり押し)
      // ここから-----
      if (i == 0) {
        if (character[i + 1] != j) {
          continue;
        }
      } else if (i == N - 1) {
        if (character[i - 1] != j) {
          continue;
        }
      } else {
        if (character[i - 1] != j && character[i + 1] != j) {
          continue;
        }
      }
      // ----- ここまで

      // vectorをコピーし、指定した要素を削除する
      vector<int> search(character);
      vector<int>::iterator it = search.begin() + i;
      it = search.erase(it);
      search.insert(it, j);

      int cnt = 1;
      for (int k = 0; k < search.size(); k += cnt) {
        cnt = 1;
        for (int l = k + 1; l < search.size(); l++) {
          if (search[k] != search[l]) {
            break;
          }
          cnt++;
        }
        // 4つ以上なら削除する
        if (cnt >= 4) {
          it = search.begin() + k;
          search.erase(it, it + cnt);
          // 途中から探索し直す
          k = -1;
          cnt = 1;
        }
      }

      ans = min(ans, (int)search.size());
      // 0なら探索終了
      if (search.empty() == true) {
        return 0;
      }
    }
  }

  return ans;
}

int main(void) {
  int N;
  vector<int> character;

  while (1) {
    // 宣言やら入力やら
    int ans = 0;
    int i;
    cin >> N;
    if (N == 0) {
      break;
    }
    character.resize(N);
    for (i = 0; i < N; i++) {
      cin >> character[i];
    }

    ans = Answer(N, character);

    cout << ans << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:



// C言語

#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

#define MAX 10000

// 解法(分けた方が見やすいかなと思って関数にした)
int Answer(int N, vector<int> character) {
  int ans = 9999999;
  // 消す基準となる玉の位置
  for (int i = 0; i < N; i++) {
    // k : 変えた後の色
    for (int j = 1; j <= 3; j++) {

      // 色を変えたところで意味のない部分は考えない(悪いけどごり押し)
      // ここから-----
      if (i == 0) {
        if (character[i + 1] != j) {
          continue;
        }
      } else if (i == N - 1) {
        if (character[i - 1] != j) {
          continue;
        }
      } else {
        if (character[i - 1] != j && character[i + 1] != j) {
          continue;
        }
      }
      // ----- ここまで

      // vectorをコピーし、指定した要素を削除する
      vector<int> search(character);
      vector<int>::iterator it = search.begin() + i;
      it = search.erase(it);
      search.insert(it, j);

      int cnt = 1;
      for (int k = 0; k < search.size(); k++) {
        cnt = 1;
        for (int l = k + 1; l < search.size(); l++) {
          if (search[k] != search[l]) {
            break;
          }
          cnt++;
        }
        // 4つ以上なら削除する
        if (cnt >= 4) {
          it = search.begin() + k;
          search.erase(it, it + cnt);
          // 最初から探索し直す
          k = -1;
        }
      }

      ans = min(ans, (int)search.size());
      // 0なら探索終了
      if (search.empty() == true) {
        return 0;
      }
    }
  }

  return ans;
}

int main(void) {
  int N;
  vector<int> character;

  while (1) {
    // 宣言やら入力やら
    int ans = 0;
    int i;
    cin >> N;
    if (N == 0) {
      break;
    }
    character.resize(N);
    for (i = 0; i < N; i++) {
      cin >> character[i];
    }

    ans = Answer(N, character);

    cout << ans << endl;
  }

  return 0;
}