题解:P10368 「LAOI-4」Colors
「LAOI-4」Colors
题目大意
给定一个长度为
题目思路
首先,我们可以观察到,对于给定的字符串,经过一定次数的操作后,字符串会进入一个循环,不断重复出现相同的状态。我们可以利用这个特点,先找到循环的起点和长度,然后直接计算出第
具体步骤如下:
-
使用
op函数对字符串进行一次操作,删除所有可消除的字符。 -
使用哈希表
mp来记录每个状态第一次出现的位置,使用数组st来存储所有出现过的状态。 -
不断对字符串进行操作,直到遇到一个之前出现过的状态。此时,我们就找到了循环的起点和长度。
-
如果
k 小于循环的起点,那么第k 次操作后的字符串就是st[k]。 -
否则,我们将
k 减去循环的起点,然后对循环的长度取模,得到在循环中的位置。最终的字符串就是st[ls + k]。
代码
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
string op(string s) {
int n = s.size();
string ns;
ns.reserve(n);
for (int i = 0; i < n; ++i) {
if (i == 0 || i == n - 1 || s[i - 1] != s[i + 1]) {
ns += s[i];
}
}
return ns;
}
string solve(string s, long long k) {
unordered_map<string, int> mp;
vector<string> st;
while (mp.count(s) == 0) {
mp[s] = st.size();
st.push_back(s);
s = op(s);
}
int ls = mp[s];
int ll = st.size() - ls;
if (k < ls) {
return st[k];
} else {
k -= ls;
k %= ll;
return st[ls + k];
}
}
int main() {
int T, id;
cin >> T >> id;
while (T--) {
int n;
long long k;
string s;
cin >> n >> k >> s;
cout << solve(s, k) << endl;
}
return 0;
}
这个算法的时间复杂度是