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

浙公网安备 33010602011771号