「0 が連続何個続くのか」を求めるタイプの問題
問題概要
数字からなる長さ の文字列 が与えられる。
「1」「2」「3」「4」「5」「6」「7」「8」「9」「0」「00」と書かれた文字列スタンプを順に押して行って、 を作りたい。
スタンプを押す回数の最小値を求めよ。
制約
考えたこと
文字列 のうち、0 以外の数字が登場したら、それに対応するスタンプを押すしかない。
工夫のしどころは「0 が連続する区間」だ。たとえば、
= "7500000470000"
のとき、7 と 5 と 4 と 7 は 1 回ずつ押すしかないが、
- "00000" は「00」「00」「0」の 3 回
- "0000" は「00」「00」の 2 回
で押せることに注意しよう。一般に、「0 が連続している区間」については、基本的に 2 個ずつ「00」で押して行って、余ったところは 1 個の「0」で押せば良いことがわかる。
残る問題は、各「0 が連続する区間」の長さを求めることだ。これは、次のように求められる。
- 文字列 を左から順にみていき、
- 0 が登場したら、その瞬間の添字を記録しておいて、0 が途切れるところまで見ていき、何個見たかを求める
結局、for
文を 1 回回すことで問題が解けるので、計算量は となる。
コード
#include <bits/stdc++.h> using namespace std; int main() { string S; cin >> S; int res = 0, prev = -1; for (int i = 0; i < S.size();) { if (S[i] == '0') { int j = i; // 0 が途切れるまで進める while (j < S.size() && S[j] == '0') j++; res += (j - i + 1) / 2; i = j; } else { res++; i++; } } cout << res << endl; }