C - Security 2 Editorial
by
sheyasutaka
以下では \(S\) の長さを \(N\) とおきます。
\(t\) の文字数は、ボタン A を押すと \(1\) 増えて、ボタン B を押すと変化しません。 なので、ボタン A を押す回数は \(N\) 回とわかります。
以下の行動の前後では \(t\) は変化しないので、以下の行動は行わないとしても操作回数の最小値は悪化しません。
- ボタン A を最初に押すよりも前に、ボタン B を押す。
- ボタン B を \(10\) 回連続で押す。
\(1 \leq i \leq N\) について、\(i\) 回目にボタン A を押してから次にボタン A を押すまでのあいだに何回ボタン B を押すかを \(b_i\) とおくと、上の議論から \(0 \leq b_i \leq 9\) としてよいです。
このとき、\(t\) の \(j\) 文字目が \(S_j\) になるのは、\((b_j + \dots + b_N) \bmod 10 = S_j\) になるときです。
\(j=N\) のときは \(b_N = S_j\) となるので、\(j<N\) のときについて考えます。 \(j+1\) 文字目について同様の式を立てると \((b_{j+1} + \dots + b_N) \bmod 10 = S_{j+1}\) となり、さきほどの式からこの式を引くことで \(b_j \equiv S_{j} - S_{j+1}\ \pmod{10}\) が分かります。 これを満たす \(b_i\) であって \(0 \leq b_i \leq 9\) の範囲にあるものは、\((10 + S_{j} - S_{j+1}) \bmod 10\) で求まります。
したがって、上で求めた \(b_j\) の値を \(1 \leq j \leq N\) について足し合わせ、さらに \(N\) を加えた値が答えとなります。
C++ での実装例を以下に示します。
#include <iostream>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::string;
int main(void){
string s;
cin >> s;
int sum = 0;
int n = s.size();
for (int i = n-1; i >= 0; i--) {
int v = s[i] - '0';
int u = ((i < n-1) ? (s[i+1] - '0') : 0);
int b = (10 + v - u) % 10;
sum += b;
}
int ans = sum + n;
cout << ans << "\n";
return 0;
}
posted:
last update:
