Codeforces Round #726 (Div. 2) E1. Erase and Extend (Easy Version)

翻译:

这是这个问题的简单版本。唯一的区别是𝑛和𝑘上的约束。只有当所有版本的问题都解决了,你才能进行hack。

你有一个字符串𝑠,你可以对它做两种类型的操作:

删除字符串的最后一个字符。
复制字符串:𝑠:=𝑠+𝑠,其中+表示连接。
每个操作可以使用任意次数(可能不使用)。

您的任务是通过对字符串𝑠执行这些操作,找到长度恰好为𝑘的字典编纂学上最小的字符串。

当且仅当下列条件之一满足时,字符串𝑎在字典结构上小于字符串𝑏:

𝑎是𝑏的前缀,但𝑎≠𝑏;
在𝑎和𝑏不同的第一个位置上,字符串𝑎在字母表中出现的字母比𝑏中相应的字母更早。
输入
第一行包含两个整数𝑛,𝑘(1≤𝑛,𝑘≤5000)—原始字符串𝑠的长度和所需字符串的长度。

第二行包含字符串𝑠,由𝑛小写英文字母组成。

输出
打印长度为𝑘的按字典顺序最小的字符串,该字符串可以通过对字符串𝑠进行操作获得。

例子
inputCopy
8 16
dbcadabc
outputCopy
dbcadabcdbcadabc
inputCopy
4个5
abcd
outputCopy
五星级
请注意
在第一个测试中,做一个副本是最优的:"dbcadabc"→"dbcadabcdbcadabc"。

在第二个测试中,最好是删除最后3个字符,然后复制字符串3次,然后删除最后3个字符,使字符串的长度为𝑘。

“abcd”→“abc”→“ab”→“a”→“aa”→“aaaa”→“aaaaaaaa”→“aaaaaaa”→“aaaaaa”→“aaaaa”。

思路:

可以删除最后一个,然后复制字符串,然后构成长度为k的,其字典序最小的字符串。所以我们直接从前往后每次比较,如果前边的字符比后面的小则可以替代,如果相同则就是比较下一位,然后来不断更新最小的串。

上边的一份代码是暴力模拟T掉,因为这样模拟,遇到全是小回文串的字符串,每次都会跑完,直接被无情卡掉。

代码:

//#include <iostream>
//#include <algorithm>
//#include <string.h>
//#include <string>
//#include <math.h>
//#include <stdio.h>
//#include<vector>
//#include<queue>
//#include<stack>
//#include<map>
//#include<set>
//#include<tuple>
//#include<numeric>
//using namespace::std;
//typedef long long  ll;
//inline __int128 read(){
//    __int128 x = 0, f = 1;
//    char ch = getchar();
//    while(ch < '0' || ch > '9'){
//        if(ch == '-')
//            f = -1;
//        ch = getchar();
//    }
//    while(ch >= '0' && ch <= '9'){
//        x = x * 10 + ch - '0';
//        ch = getchar();
//    }
//    return x * f;
//}
//inline void print(__int128 x){
//    if(x < 0){
//        putchar('-');
//        x = -x;
//    }
//    if(x > 9)
//        print(x / 10);
//    putchar(x % 10 + '0');
//}
//int n,k;
//string s;
//int main(){
//    ios::sync_with_stdio(false);
//    cin.tie(); cout.tie();
//    int jk=0;
//    cin>>n>>k>>s;
//    for (int i =1; i<n; i++) {
//        if (s[i]!=s[i-1]) {
//            jk=1;break;
//        }
//    }
//    if (n==1||!jk) {
//        for (int i =1; i<=k; i++) {
//            cout<<s[0];
//        }cout<<"\n";
//        return 0;
//    }
//    char ss=s[0];
//    string a;
//    a=a+s[0];
//    int bj=0;
//    for (int i =1; i<n; i++) {
//        if (s[i]>ss) {
//            bj=i;
//            break;
//        }
//        if (s[i]==ss) {
//            string dd="";
//            dd=s[i];
//            int l=1,r=i+1;
//            if (s[l]<s[r]) {
//                break;
//            }
//            while (r<n&&s[l]==s[r]) {
//                dd=dd+s[l];
//                l++,r++;
//                if (s[l]<s[r]) {
//                    bj=r;
//                    break;
//                }
//            }
//            if (bj!=0) {
//                break;
//            }
//        }
//        a=a+s[i];
//    }
//    for (int i =1; i<=k/a.size(); i++) {
//        cout<<a;
//    }
//    for (int i =0; i<k%a.size(); i++) {
//        cout<<a[i];
//    }cout<<"\n";
//    return 0;
//}
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
using namespace::std;
typedef long long  ll;
inline __int128 read(){
    __int128 x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}
int n,m;
string s,d,f;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>n>>m>>s;
    
    d=s[0];
    for (int i =2; i<=n; i++) {
        f=s.substr(0,i);
        if (f+d<d+f) {
            d=f;
        }
    }
    for (int i =0; i<m; i++) {
        cout<<d[i%d.size()];
    }cout<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值