題意:如果一個字符串不是所有循環節裏面的最小字典序,就將它分塊。問你最少分塊之後的字符串。
題解:按照題意模擬就行,這裏有幾個地方得考慮。暴力隊友都認爲過不了。。。。但是我認爲是可以的,第一個是因爲暴力也不能純的暴力,有很多細節可以優化。
1.判斷當前字符串是不是最小的時候,我用的兩個字符串相加然後取substr,一個是期望c++能夠有點優化。。。一個一個的取就變成n^4了,聊勝於無吧。。(但其實我覺得substr還是on的)
2.代碼有兩次跳躍,如果取到最小字典序直接跳躍到之後的字符串開始繼續跑,這裏省略了一部分時間,然後取到如果比當前字符串小的還要break,這裏又省略了一部分時間
3.隊友覺得過不去的原因是上屆爲300*200*200*200直接爆炸,我猜測的一個原因是取到上界字符串很少。。。數據很難出,所以稍微優化一下應該沒問題
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mem(s) memset(s, 0, sizeof(s))
const int INF = 0x3f3f3f3f;
const double eps = 1e-8;
const int maxn = 1e6+5;
const int mod = 998244353;
typedef long long ll;
vector<int>res1;
void solve1(string tmp){
string s=tmp;
string s1;
for(int i=0;i<s.size();i++){
//cout<<i<<endl;
for(int q=s.size()-i;q>=1;q--){
s1=s.substr(i,q);
string tmp2=s1+s1;
int ff=1;
for(int j=0;j<s1.size();j++){
string tmp=tmp2.substr(j,q);
if(tmp<s1){
ff=0;
//cout<<s1<<endl;
//cout<<tmp<<endl;
break;
}
}
if(ff){
res1.push_back(i+q-1);
i+=(q-1);
break;
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
string s;
cin>>s;string tmp=s;
res1.clear();
solve1(s);
int flag=0;
//cout<<res1.size()<<endl;
for(int i=0;i<s.size();i++){
printf("%c",s[i]);
if(flag<res1.size()&&i==res1[flag])printf(" "),flag++;
}
printf("\n");
}
return 0;
}