E1. Erase and Extend (Easy Version)

https://codeforces.com/problemset/problem/1537/E1

题意:给定一个长度为n的字符串s和一个整数k,现在可对s进行两种操作,不限制操作次数,问s的长度变为k的逻辑上的最小字符串是多少。操作:1、s删除最后一个字符; 2、s += s

思路:设置一个前缀字符串pref,初始时为s[0]。用前缀数组构造第一个长度为k的字符串。随后从下标1~n遍历s,如果s[i] < s[0],说明将s[i]加入到pref后,得到的字符串在逻辑上可能会更小。如果s[i] > s[0],说明如果构造字符串时,不使用s[i]一定比使用s[i]得到的字符串更优,直接中断循环。

总结:一开始的思路是,找各种字符跟s[0]的关系..然后想办法一个位置一个位置构造,构造出一个最小的字符串。但是总有示例过不去, 因为这种构造逻辑,太复杂了,要考虑很多细节进来。 这个题解,应该是属于贪心算法这一类的,如果s[0]是a,那肯定输出字符串就是全a了。如果有zyx..cba这样的字符串构造,或者abc..xyz这种字符串,就可以发现一点点规律了。 这种题目,还是得先看看对于不同的字符串进行操作,能不能发现什么通用的规律。

inline void solve() {
    int n, k;
    cin >> n >> k;

    string s;
    cin >> s;

    auto get = [](string s, int k) {
        while (s.size() < k) {
            s += s;
        }
        while (s.size() > k) {
            s.pop_back();
        }
        return s;
    };

    string pref;
    pref += s[0];

    string ans = get(pref, k);
    for (int i = 1; i < n; ++i) {
        if (s[i] > s[0]) {
            break;
        }
        pref += s[i];
        ans = min(ans, get(pref, k));
    }

    cout << ans << '\n';
}
posted @ 2025-12-11 10:00  _Yxc  阅读(5)  评论(0)    收藏  举报