持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
题目描述
这是代码源5月31日的div2每日一题
最长的 X - 题目 - Daimayuan Online Judge
给定一个由 X 和 . 组成的字符串 S。
你能对字符串 S 做以下操作 0 到 K 次(包括 0 和 K):
将一个 . 替换为 X
请问操作完的字符串 S 中最多可能有多少个连续的 X?
输入格式
第一行一个字符串 S
第二行一个整数 K
输出格式
一个整数,表示答案
样例输入
XX...X.X.X.
2
样例输出
5
数据范围
对于全部数据保证 1≤|S|≤2×105,0≤K≤2×105。
问题解析
双指针写法,为了方便我们这里先预处理一个前缀和数组,我们把字符串的'.'看成1,'X'看成0来计算前缀和。
然后快慢指针遍历前缀和数组,如果快指针r到慢指针l这一段的区间和:
小于等于k,说明这一段的‘.'我们都可以把他们变成’X',那么这一段都可以是‘X',快指针走一步。
如果大于k了,说明这一段的’.'我们并不能全变成‘k',即这一段并不是连续的'X',那么我们慢指针走一步,如果两个指针是在同一个位置,那么快指针也要走一步。
每次计算完一个区间值后,我们更新一下最大区间长度,最后把维护的值输出即可。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include <sstream>
#define endl '\n'
#define int ll
typedef long long ll;
typedef pair<ll, ll>PII;
typedef unsigned long long ull;
string s;
int k, n;
int sum[200005];
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cin >> s >> k;
int n=s.size();
if (k > n)
{
cout << n << endl;
return 0;
}
for (int i = 1; i <= n; i++)
{
if (s[i - 1] == 'X')sum[i] = sum[i - 1];
else sum[i] = sum[i - 1] + 1;
}
int res = 0, l = 1, r = 1;
while (r <= n)
{
if (sum[r] - sum[l - 1] <= k)
{
r++;
res = max(r - l, res);
}
else
{
if (l == r)r++;
l++;
}
}
cout << res;
return 0;
}