【プログラミングコンテスト】AtCoder Beginner Contest 120③
最近午前に起きることができない人間になってしまいました、ねむーです。
今回はAtCoder(https://atcoder.jp/contests/abc120)にて開催されました、AtCoder Beginner Contest 120の第3回目です。
今回は、第3問「C - Unification」の問題と僕との戦闘記です。
0.はじめに
1.問題文
机の上に N 個のキューブが縦に積まれています。長さ N の文字列 S が与えられます。
下から i 番目のキューブの色は、 S の i 文字目が 0 のとき赤色、1 のとき青色です。
あなたは、赤色のキューブと青色のキューブが隣り合っているような部分を選んで、それら 2 個のキューブを取り除く操作を何度でも行えます。
このとき、取り除いたキューブの上にあったキューブは真下の物体の上に落下します。
最大で何個のキューブを取り除けるでしょうか。
2.入力例
入力:
11011010001011
出力:
12
3.初見の感想
- 再帰的に1と0が含まれてる部分を探して、文字列を小さくする方法を考えました
- するとTLEになりました(悲しい…)
4.学びポイント
- どうやったら一回のループで計算できるか…
- スタックを使いましょう!
- ちなみにこの問題は0と1の個数の差が答えになるので、その方法でも解けます(これが一番簡単だと思います…)
5.コードの簡単な解説
- 一文字ずつ読み込んでスタックに積みます、10,01のように消える場合ならPopして消します
for (int i = 0; i < str.Length; i++) { stack.Push(str[i]); if (stack.Count > 1) { var a = stack.Pop(); var b = stack.Pop(); if (a != b) { count += 2; } else { stack.Push(b); stack.Push(a); } } }
6.全コード
using System; using System.Collections.Generic; public class Program { static void Main() { var str = Console.ReadLine(); var stack = new Stack<char>(); var count = 0; for (int i = 0; i < str.Length; i++) { stack.Push(str[i]); if (stack.Count > 1) { var a = stack.Pop(); var b = stack.Pop(); if (a != b) { count += 2; } else { stack.Push(b); stack.Push(a); } } } Console.WriteLine(count); } }
7.最後に
そろそろ計算量にも目を向けていきたいですね…