2019牛客暑期多校訓練營(第七場)A String

題意:如果一個字符串不是所有循環節裏面的最小字典序,就將它分塊。問你最少分塊之後的字符串。

題解:按照題意模擬就行,這裏有幾個地方得考慮。暴力隊友都認爲過不了。。。。但是我認爲是可以的,第一個是因爲暴力也不能純的暴力,有很多細節可以優化。

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章