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

#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#include <sstream> // istringstream
#include <string>
#include <vector>

using namespace std;

// 最悪ケースでN^2かかるのでまずい
// string del_kakko(string s){
//     while(true){
//         int ir_idx = s.find("()");
//         if(ir_idx == string::npos){
//             break;
//         }
//         s = s.erase(ir_idx, 2);
//     }
//     return s;
// }
string del_kakko(string s) {
  int left = 0, right = 0;
  for (int i = 0; i < s.length(); ++i) {
    if (s[i] == '(') {
      left++;
    } else if (s[i] == ')') {
      if (left > 0) {
        left--;
      } else {
        right++;
      }
    }
  }
  string ret = "";
  for (int i = 0; i < right; ++i)
    ret += ")";
  for (int i = 0; i < left; ++i)
    ret += "(";
  return ret;
}

// tuple<int, int> del_kakko(string s) {
//     int left = 0, right = 0;
//     for(int i=0; i<s.length(); ++i){
//         if(s[i] == '('){
//             left++;
//         }
//         else if(s[i] == ')'){
//             if(left > 0){
//                 left--;
//             }
//             else{
//                 right++;
//             }
//         }
//     }
//     return forward_as_tuple(left, right);
// }

// argsort https://teratail.com/questions/150380
vector<int> argsort(vector<int> array) {
  vector<int> indices(array.size());
  iota(indices.begin(), indices.end(), 0);
  // ソートする。
  sort(indices.begin(), indices.end(),
       [&array](size_t i1, size_t i2) { return array[i1] < array[i2]; });
  // for (auto v : indices)
  //     cout << v << " ";
  // cout << endl;
  return indices;
}

int main() {
  int N;
  cin >> N;
  string S[N];
  for (int i = 0; i < N; ++i)
    cin >> S[i];

  vector<vector<int>> X(N, vector<int>(2));

  for (int i = 0; i < N; ++i) {
    // int left, right;
    // tie(left, right) = del_kakko(S[i]);
    // X[i][0] = left;
    // X[i][1] = right;
    S[i] = del_kakko(S[i]);
    if (S[i].length() == 0) {
    } else if (S[i][0] == '(') {
      X[i][0] = S[i].length();
    } else if (S[i][0] == ')' && S[i][S[i].length() - 1] == ')') {
      X[i][1] = S[i].length();
    } else {
      X[i][1] = S[i].find('(');
      X[i][0] = S[i].length() - X[i][1];
    }
  }
  // cout << "d " << X[0][0] << " " << X[0][1] << " " << X[1][0] << " " <<
  // X[1][1] << endl;

  string ans = "";
  int life = 0;
  // '('のみのもの
  for (int i = 0; i < N; ++i) {
    if (X[i][1] == 0) {
      ans += S[i];
      S[i] = "";
      life += X[i][0];
    }
  }

  // '('の方が多いもの, ただし制限がある
  // ここの処理が最悪ケースでまずい
  // 条件式一つで処理速度が段違いになった 難しい
  // for(int ii=0; ii<N; ++ii){
  //     int count = 0;
  //     for(int i=0; i<N; ++i){
  //         if(X[i][0] >= X[i][1] && X[i][1] != 0 && X[i][1] <= life){
  //             ans += S[i];
  //             S[i] = "";
  //             life -= X[i][1];
  //             life += X[i][0];
  //             count++;
  //         }
  //     }
  //     if(count == 0){
  //         break;
  //     }
  // }
  // // '('の方が多いもの
  // for(int i=0; i<N; ++i){
  //     if(X[i][0] >= X[i][1] && X[i][1] != 0){
  //         ans += S[i];
  //         S[i] = "";
  //     }
  // }

  // vector<int> sample = {0, 1, 2, 1, 2, 5};
  // vector<int> sample_indexs = argsort(sample);

  // sortして, )が少ないものから追加
  // 上記と同じ内容にできれば良い
  vector<int> array(N);
  for (int i = 0; i < N; ++i)
    array[i] = X[i][1];
  vector<int> indexs = argsort(array);
  for (int i = 0; i < N; ++i) {
    int idx = indexs[i];
    // cout << "d " << X[idx][0] << " " << X[idx][1] << endl;
    if (X[idx][0] >= X[idx][1] && X[idx][1] != 0) {
      ans += S[idx];
      S[idx] = "";
    }
  }

  // ')'の方が多いもの
  for (int i = 0; i < N; ++i) {
    if (X[i][0] < X[i][1] && X[i][0] != 0) {
      ans += S[i];
      S[i] = "";
    }
  }
  // ')'のみのもの
  for (int i = 0; i < N; ++i) {
    if (X[i][0] == 0) {
      ans += S[i];
    }
  }

  // cout << "d " << ans << endl;
  // int left, right;
  // tie(left, right) = del_kakko(ans);
  ans = del_kakko(ans);
  if (ans.length() == 0) {
    // if(left == 0 && right == 0){
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#include <sstream> // istringstream
#include <string>
#include <vector>

using namespace std;

// 最悪ケースでN^2かかるのでまずい
// string del_kakko(string s){
//     while(true){
//         int ir_idx = s.find("()");
//         if(ir_idx == string::npos){
//             break;
//         }
//         s = s.erase(ir_idx, 2);
//     }
//     return s;
// }
string del_kakko(string s) {
  int left = 0, right = 0;
  for (int i = 0; i < s.length(); ++i) {
    if (s[i] == '(') {
      left++;
    } else if (s[i] == ')') {
      if (left > 0) {
        left--;
      } else {
        right++;
      }
    }
  }
  string ret = "";
  for (int i = 0; i < right; ++i)
    ret += ")";
  for (int i = 0; i < left; ++i)
    ret += "(";
  return ret;
}

// tuple<int, int> del_kakko(string s) {
//     int left = 0, right = 0;
//     for(int i=0; i<s.length(); ++i){
//         if(s[i] == '('){
//             left++;
//         }
//         else if(s[i] == ')'){
//             if(left > 0){
//                 left--;
//             }
//             else{
//                 right++;
//             }
//         }
//     }
//     return forward_as_tuple(left, right);
// }

// argsort https://teratail.com/questions/150380
vector<int> argsort(vector<int> array) {
  vector<int> indices(array.size());
  iota(indices.begin(), indices.end(), 0);
  // ソートする。
  sort(indices.begin(), indices.end(),
       [&array](size_t i1, size_t i2) { return array[i1] < array[i2]; });
  // for (auto v : indices)
  //     cout << v << " ";
  // cout << endl;
  return indices;
}

int main() {
  int N;
  cin >> N;
  string S[N];
  for (int i = 0; i < N; ++i)
    cin >> S[i];

  vector<vector<int>> X(N, vector<int>(2));

  for (int i = 0; i < N; ++i) {
    // int left, right;
    // tie(left, right) = del_kakko(S[i]);
    // X[i][0] = left;
    // X[i][1] = right;
    S[i] = del_kakko(S[i]);
    if (S[i].length() == 0) {
    } else if (S[i][0] == '(') {
      X[i][0] = S[i].length();
    } else if (S[i][0] == ')' && S[i][S[i].length() - 1] == ')') {
      X[i][1] = S[i].length();
    } else {
      X[i][1] = S[i].find('(');
      X[i][0] = S[i].length() - X[i][1];
    }
  }
  // cout << "d " << X[0][0] << " " << X[0][1] << " " << X[1][0] << " " <<
  // X[1][1] << endl;

  string ans = "";
  int life = 0;
  // '('のみのもの
  for (int i = 0; i < N; ++i) {
    if (X[i][1] == 0) {
      ans += S[i];
      S[i] = "";
      life += X[i][0];
    }
  }

  // '('の方が多いもの, ただし制限がある
  // ここの処理が最悪ケースでまずい
  for (int ii = 0; ii < N; ++ii) {
    int count = 0;
    for (int i = 0; i < N; ++i) {
      if (X[i][0] >= X[i][1] && X[i][1] != 0 && X[i][1] <= life) {
        ans += S[i];
        S[i] = "";
        life -= X[i][1];
        life += X[i][0];
        count++;
      }
    }
    if (count == 0) {
      break;
    }
  }
  // '('の方が多いもの
  for (int i = 0; i < N; ++i) {
    if (X[i][0] >= X[i][1] && X[i][1] != 0) {
      ans += S[i];
      S[i] = "";
    }
  }

  // sortして, )が少ないものから追加
  // 上記と同じ内容にできれば良い
  // vector<int> array(N);
  // for(int i=0; i<N; ++i) array[i] = X[i][1];
  // vector<int> indexs = argsort(array);
  // for(int i=0; i<N; ++i){
  //     int idx = indexs[i];
  //     if(X[idx][0] >= X[idx][1]){
  //         ans += S[i];
  //         S[i] = "";
  //     }
  // }

  // ')'の方が多いもの
  for (int i = 0; i < N; ++i) {
    if (X[i][0] < X[i][1] && X[i][0] != 0) {
      ans += S[i];
      S[i] = "";
    }
  }
  // ')'のみのもの
  for (int i = 0; i < N; ++i) {
    if (X[i][0] == 0) {
      ans += S[i];
    }
  }

  // cout << "d " << ans << endl;
  // int left, right;
  // tie(left, right) = del_kakko(ans);
  ans = del_kakko(ans);
  if (ans.length() == 0) {
    // if(left == 0 && right == 0){
    cout << "Yes" << endl;
  } else {
    cout << "No" << endl;
  }

  return 0;
}