题目大意
题目链接
给你一个长为n的字符串, 问k为多少时, 字符串的字典序最小
k的定义, 翻转 s[i : i + k − 1] | 1 <= i <= n - k + 1
。
分析
写几个找规律。
1 2 3 4 5 6
| k = 2时 abcd 结果是 bcd|a abcde 结果是 bcde|a k = 3是 abcd 结果是 cd|ab abcde 结果是 cde|ba
|
可以看得出来, 结果是又两部分构成, 前一部分是 s[k : len], 后一部分 如果 n - k
是奇数, 那么 为s[1 :k], 如果 n - k
是偶数, 为 s[1 : k] 的翻转。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
#include <bits/stdc++.h> #define eps 1e-8 using namespace std; #define ms(a, b) memset((a), (b), sizeof(a)) typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; const int N = 1e5 + 5; const int M = 1e6 + 5; const int INF = 0x3f3f3f3f; const ll ll_max = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7;
inline ll read() { ll res = 0;bool f = 0;char ch = getchar(); while (ch < '0' || ch > '9') {if (ch == '-') f = 1;ch = getchar();} while (ch <= '9' && ch >= '0') {res = (res << 3) + (res << 1) + ch - '0';ch = getchar();} return f ? (~res + 1) : res; } string s, s1, s2, ans; int main(){ int t = read(); while(t--){ int n = read(); cin >> s; ans = s; int pos = 1; for (int i = 0; i < n; ++i){ s1 = s.substr(0, i); s2 = s.substr(i); string tmp = s2; if ((n - i) & 1) reverse(s1.begin(), s1.end()); tmp += s1; if (tmp < ans){ ans = tmp; pos = i + 1; } } cout << ans << "\n" << pos << "\n"; } return 0; }
|
恰似你一低头的温柔,较弱水莲花不胜寒风的娇羞, 我的心为你悸动不休。 --mingfuyan
千万不要图快——如果没有足够的时间用来实践, 那么学得快, 忘得也快。