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

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值