[题解] AT_ABC409_D String Rotation
题目
您将得到一个长度为 \(N\) 的字符串 \(S=S_1 S_2\dots S_n\) ,该字符串由小写英文字母组成。
您将在 \(S\) 上仅执行一次以下操作:选择长度至少为 \(1\) 的 \(S\) 的连续子字符串,并将其循环左移 \(1\) 。即,选择整数 \(1 \leq l \leq r \leq N\) ,在 \(S\) 的第 \(r\) 个字符的右侧插入 \(S_l\) 然后删除 \(S\) 的第 \(l\) 个字符。例如:将abcde中的cd循环左移一次,就会得到acdbe。
在所有可能的字符串中找出 \(S\) 在运算后可以成为的字典序最小的字符串。
给出了 \(T\) 个测试用例,因此请解决每个测试用例。
\(1 \leq T,N \leq 10^5\)
\(S\) 是由小写英文字母组成的长度为 \(N\) 的字符串。
单个输入文件中所有测试用例的 \(N\) 的总和最多为 \(10^5\) 。
思路
比较容易想到思路的一道题。因为只执行一次,所以贪从前往后贪心的看那些字母可以往前移,当然,越前面肯定越好。所以遇到第一个可以交换的字母,就考虑在它身后连续的字符串能否跟着它一起向前移动(具体看代码)。
代码
#include <bits/stdc++.h>
using namespace std;
int n, j;
string s;
inline int read() {
    int x;
    cin >> x;
    return x;
}
inline void solve() {
    n = read();
    cin >> s;
    s = " " + s;
    j = 1;
    for (int i = 1; i <= n; i++)
        if (s[i] > s[i + 1]) {
            while (j < i) {
                cout << s[j];
                j++;
            }
            j++;
            while (j <= n && s[j] <= s[i]) {
                cout << s[j];
                j++;
            }
            cout << s[i];
            while (j <= n) {
                cout << s[j];
                j++;
            }
            break;
        }
    cout << endl;
    return;
}
signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int _ = read();
    while (_--) solve();
    return 0;
}

                
            
        
浙公网安备 33010602011771号