Problem p02686 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

string shorten(const string &s) {
  string res;
  for (const char i : s) {
    if (res.back() == '(' && i == ')')
      res.pop_back();
    else
      res.push_back(i);
  }
  return res;
}

struct brace {
  int left;
  int right;

  brace operator+(const brace &other) {
    int facing = min(this->right, other.left);
    return brace{this->left + other.left - facing,
                 this->right - facing + other.right};
  }
};

bool operator<(const brace a, const brace b) { return a.right > b.right; }

brace toBrace(const string &s) {
  brace res = brace{0, 0};
  for (char i : s)
    (i == ')' ? res.left : res.right)++;
  return res;
}

int main() {
  int n;
  cin >> n;
  vector<brace> s;
  for (int i = 0; i < n; ++i) {
    string S;
    cin >> S;
    S = shorten(S);
    if (S != "")
      s.push_back(toBrace(S));
  }
  brace rightOpen{0, 0};
  brace leftOpen{0, 0};
  vector<brace> bothOpen;
  for (const auto &i : s) {
    if (i.left == 0)
      rightOpen.right += i.right;
    else if (i.right == 0)
      leftOpen.left += i.left;
    else
      bothOpen.push_back(i);
  }
  sort(bothOpen.begin(), bothOpen.end());
  int cnt = 0;
  for (int i = 0; i < bothOpen.size(); ++i) {
    for (auto &j : bothOpen) {
      if (j.left <= rightOpen.right) {
        rightOpen = rightOpen + j;
        j.left = 1145141919;
        cnt++;
        break;
      }
    }
  }
  rightOpen = rightOpen + leftOpen;
  puts(cnt == bothOpen.size() && rightOpen.left == 0 && rightOpen.right == 0
           ? "Yes"
           : "No");
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

string shorten(const string &s) {
  string res;
  for (const char i : s) {
    if (res.back() == '(' && i == ')')
      res.pop_back();
    else
      res.push_back(i);
  }
  return res;
}

struct brace {
  int left;
  int right;

  brace operator+(const brace &other) {
    int facing = min(this->right, other.left);
    return brace{this->left + other.left - facing,
                 this->right - facing + other.right};
  }
};

bool operator<(const brace a, const brace b) { return a.right > b.right; }

brace toBrace(const string &s) {
  brace res = brace{0, 0};
  for (char i : s)
    (i == ')' ? res.left : res.right)++;
  return res;
}

int main() {
  int n;
  cin >> n;
  vector<brace> s;
  for (int i = 0; i < n; ++i) {
    string S;
    cin >> S;
    S = shorten(S);
    if (S != "")
      s.push_back(toBrace(S));
  }
  brace rightOpen{0, 0};
  brace leftOpen{0, 0};
  vector<brace> bothOpen;
  for (const auto &i : s) {
    if (i.left == 0)
      rightOpen.right += i.right;
    else if (i.right == 0)
      leftOpen.left += i.left;
    else
      bothOpen.push_back(i);
  }
  sort(bothOpen.begin(), bothOpen.end());
  int cnt = 0;
  for (int i = 0; i < bothOpen.size(); ++i) {
    if (cnt < i)
      break;
    for (auto &j : bothOpen) {
      if (j.left <= rightOpen.right) {
        rightOpen = rightOpen + j;
        j.left = 1145141919;
        cnt++;
        break;
      }
    }
  }
  rightOpen = rightOpen + leftOpen;
  puts(cnt == bothOpen.size() && rightOpen.left == 0 && rightOpen.right == 0
           ? "Yes"
           : "No");
}