🕌
AGC 048 | A - atcoder < S
問題
考えたこと
(1) -1の場合
どのようにしてもatcoder
より辞書順が小さい場合。atcoder
は先頭がa
なのでa
のみの文字列だとatcoder
より辞書順が常に小さくなってしまう。
(2) 0の場合
すでに辞書順の場合は交換しなくてよい。
(3) 以上の場合
前述の(1), (2)の条件より文字列は以下の条件を満たす。
- 先頭は必ず
a
である。 -
a
以外のものが含まれている。
先頭から走査し、最初に現れるa
以外の文字をPOS - 1
必要である。
その移動した状態で辞書順になっていればそれが最適解。なっていなければ
コード
実装時のTips
- 文字列aとbの辞書順の比較は
a < b
でできる - iとjの位置の文字のスワップは
swap(s[i], s[j])
でできる
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
const int MOD = 1e9 + 7;
int main() {
int T;
cin >> T;
string tar = "atcoder"; // target
for (int i = 0; i < T; i++) {
string s;
cin >> s;
// 初期状態ですでに辞書順になっているか
if (tar < s) {
cout << 0 << endl;
continue;
}
// すべてaか調べる
bool isOnlyA = true;
int pos = -1;
for (int j = 0; j < s.size(); j++) {
char c = s[j];
if (c != 'a') {
isOnlyA = false;
pos = j;
break;
}
}
if (isOnlyA) {
cout << -1 << endl;
continue;
}
// どこかにaでないのがある. その場合はそれをs[1]のとまで入れ替えて辞書順か調べる
for (int j = pos; j > 1; j--) {
swap(s[j], s[j - 1]);
}
if (tar < s) {
cout << pos - 1 << endl;
} else {
cout << pos << endl;
}
}
}
Discussion