競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 310C

ABC310C

最初は,回文かそうでないかで分けて考えていた. 回文を入れる string 型の set を a, そうでない文を入れる set を b とする.ただし,b に入れるときは, \(s_{i}\) と \(reverse(s_{i})\) の両方を入れる. \(i \in N\) の \(s_{i}\) を \(a,b\) に分配した後, a.size() + b.size()/2 が答え.

改良:
string 型の set st を用意する. \(s_{i}\) が回文かそうでないかは区別せずに, st に \(s_{i}\) と \(reverse(s_{i})\) を入れる. 入れる前に,\(s_{i}\) が st に入っているか判定して, 入ってないときだけカウントする.


補足:
同値関係 \(x \sim y \) で類別した個数を数えたいのだが, \(i \in N\) を動かして類を作っていく際, 新しい類を作るときだけカウントするということ.
ここで,文字列 \(x,y\) に対して \(x \sim y\) であることを, \(x = y \) または \(x = reverse(y)\) と定義する.

使っている記号,マクロ等 "https://ecsmtlir.hatenablog.com/entry/2022/12/23/131925"

int main() {
  ll n;
  cin >> n;
  vector<string> s(n); cinv(s);


  set<string> st;
  ll ans = 0;
  rep(i,n){
    if(!in(s[i], st)) ans++;
    st.insert(s[i]);
    reverse(all(s[i]));
    st.insert(s[i]);
  }
  cout << ans << endl;


  return 0;
}