初始有一个字符串s,串的长度L不超过2500。你可以对串中一个子串进行一次翻转,确切的说,你可以选择一对整数
{ x,y } 其中0<=x<=y<L,然后翻转字符串中索引在x到y区间上的子串,将该串从s[x]s[x+1]...s[y]变为s[y]...s[x+1]s[x]。例如, s = "abcdefg",{ x,y } 取 { 2,5 } 那么翻转后是 "abfedcg",如果取 { 0,1 } 结果是 "bacdefg",如果取 { 3,3 } 那结果是 "abcdefg"(即没变)。你的目的是翻转一次后,使字符串的字典序尽可能的小,那么问最优的 { x,y } 是多少?如果存在多组解能使s变化后字典序最小,那么输出其中x最小的那组解,如果还有多组解,那么输出y最小的解。
Input
多组测试数据,第一行一个整数T,表示测试数据数量,1<=T<=5 之后有T组结构相同的数据: 每组包含一行一个字符串s,其中s的长度L满足1<=L<=2500且s只包含小写字母'a'~'z'
Output
一组数据输出一行两个整数,即最优的翻转子序列的区间索引x,y
Input示例
2 abdc aabbcc
Output示例
2 3 0 0#include <cstring> #include <iostream> using namespace std; char input[2600]; void updateX(int y, int &x) { for (int i = x-1; i >= 0; i--) { if (input[y] < input[i]) { x = i; } } } int main() { int t; cin >> t; for (int i = 0; i < t; i++) { cin >> input; int x, y; x = 0; y = 0; int size = strlen(input); for (int i = 1; i < size; i++) { if (input[i] < input[i-1]) { x = i - 1; y = i; break; } } updateX(y, x); for (int i = y+1; i < size; i++) { if (input[i] < input[y]) { y = i; updateX(y, x); } else if (input[i] == input[y]) { int a = y - 1; int b = i - 1; while (a >= x) { if (input[b] < input[a]) { y = i; break; } else if (input[b] > input[a]) { break; } a--; b--; } if (a < x) { a = y + 1; while (a <= i) { if (input[b] < input[a]) { y = i; break; } else if (input[b] > input[a]) { break; } a++; b--; } } } } cout << x << " " << y << endl; } return 0; }