原题链接
首先容易想到所o
相邻的?
全部都是一种可能的
所以可以对字符串先把这种?
先处理一遍
接下来再想想特殊情况,因为题目保证有解
假设我们初始o
的数量为cnt
那么肯定满足
c
n
t
≤
k
cnt \leq k
cnt≤k,同时?
的个数一定可以使得
c
n
t
=
k
cnt=k
cnt=k
简单特判若
c
n
t
=
k
cnt =k
cnt=k所有?
肯定是.
思考若干个连续?
最多能够产生几个o
呢?
假设?
个数为len,最多能够产生
(
l
e
n
+
1
)
/
/
2
(len+1)//2
(len+1)//2个,但是长度为奇数,最多产生的生成方式只有一种,长度为偶数则有多种最多产生方式。
那么就不难想到若是每一段连续的?
都全力产出o
以后,我们的o
数量才能满足k
。
那么此时对于奇数长度的连续?
来说,他的生成方式是确定的,剩余其他情况的?
都是不确定。
若是不需要全力产出就能够使得
c
n
t
=
k
cnt=k
cnt=k那么哪一段作为不全力发挥的都是有可能的,此时?
都是不确定的。
参考代码
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 1e6 + 10;
const int mod = 998244353;
#define endl '\n'
bool flag = false;
int cnt = 0;
#define all(x) x.begin(), x.end()
// int xx[] = { 1,0,-1,0 };
// int yy[] = { 0,1,0,-1 };
i64 qp(i64 a, i64 b)
{
i64 res = 1;
a %= mod;
while (b)
{
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
void solve()
{
int n, k;
cin >> n >> k;
string s;
cin >> s;
for (int i = 0; i < n; i++)
{
if (s[i] == 'o')
{
if (i)
s[i - 1] = '.';
if (i + 1 < n)
s[i + 1] = '.';
}
}
bool flag = true;
int sum = count(all(s), 'o');
if (sum == k)
{
for (int i = 0; i < n; i++)
if (s[i] == '?')
s[i] = '.';
}
//.???.
for (int i = 0; i < n; i++)
{
if (s[i] == '?')
{
int j = i;
while (j < n && s[j] == '?')
j++;
sum += (j - i + 1) / 2;
i = j;
}
}
if (sum == k)
{
for (int i = 0; i < n; i++)
{
if (s[i] == '?')
{
int j = i;
while (j < n && s[j] == '?')
j++;
if ((j - i) % 2 != 1)
{
i = j;
continue;
}
for (int k = i; k < j; k += 2)
s[k] = 'o';
for (int k = i + 1; k < j; k += 2)
s[k] = '.';
i = j;
}
}
}
cout << s << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--)
solve();
}