题解:B4205 [常州市赛 2021] 特殊字符
lly31415926 · · 题解
题目要求处理
- 续
x 个特殊字符表示要将后续x 个字符复制x 次。 - 需要找到破译后字符串的第
k 个字符。
一 暴力出奇迹
遍历
实时构建破译字符串:
- 遇到普通字符直接追加。
- 遇到特殊字符时执行复制操作。
提前终止:当字符串长度
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, K;
string s;
cin >> n >> K >> s;
string ans(26, '*');
for (char c = 'a'; c <= 'z'; c++) {
string d;
int i = 0;
while (i < n && d.size() < K) {
if (s[i] != c) {
d += s[i++];
continue;
}
int x = 0;
while (i < n && s[i] == c) x++, i++;
int t = min(x, n-i);
string p = s.substr(i,t);
i += t;
while (x-- && d.size() < K) d += p;
}
if (d.size() >= K) ans[c-'a'] = d[K-1];
}
cout << ans;
}
战绩:
十年 OI 一场空,暴力解题见祖宗。
回归正题:
很显然,当
所以,
我们只可以不实际构建字符串,而是通过数学计算直接定位第
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n, k;
string s;
cin >> n >> k >> s;
string r(26, '*');
for (char c = 'a'; c <= 'z'; ++c) {
long long p = 0;
long long i = 0;
char a = '*';
while (i < n && a == '*') {
if (s[i] != c) {
if (++p == k) a = s[i];
++i;
continue;
}
long long x = 0;
while (i < n && s[i] == c) ++x, ++i;
long long t = min(x, n-i);
if (p + x*t >= k) {
a = s[i + (k-p-1)%t];
break;
}
p += x*t;
i += t;
}
if (a != '*') r[c-'a'] = a;
}
cout << r;
return 0;
}