おじさんの競プロ記録

自分の力で解答できた問題を振り返り、理解を深めたいです。

AtCoder Regular Contest 108 B - Abbreviate Fox

問題

問題文へ 長さNの英小文字のみからなる文字列sが与えられます。

sからfoxを1つ選んで除いて間を詰める操作を、可能な限り続けます。

操作ができなくなった時点のsの長さを出力してください。

制約

  • {1 \leqq N \leqq 2 \times 10^5}
  • sは英小文字のみからなる長さNの文字列

考えたこと

fofoxxなど取り除いた後にまた取り除く必要があります。foxを取り除く処理はstringの連結を使うと時間がかかりそうです。

文字列を先頭から順にstackに入れて、xの場合は取り出してofならば取り除いたとして数え上げ、違った場合はstackに戻すこととしました。

コード

#define _GIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define all(v) v.begin(), v.end()
using namespace std;
using ll = long long;


int main(void) {
  int N;
  cin >> N;
  string s;
  cin >> s;

  stack<char> st;
  int count = 0;
  rep(i, s.length()) {
    if (s[i] == 'x' && i >= 2) {
      char temp = st.top();
      st.pop();
      if (temp == 'o' && st.top() == 'f') {
        st.pop();
        ++count;
      } else {
        st.push(temp);
        st.push(s[i]);
      }
    } else {
      st.push(s[i]);
    }
  }

  cout << N - count * 3 << endl;
  
  return 0;
}

解説を読んで

stackなどを使わなくてもできたようです。stringについて学ぶことがまだまだあります。