携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情 阿宁经常在周末睡大觉。阿宁在膜法书上了解到,她睡觉时会产生字符串 s,计算出她的睡觉质量为
其中定义 w(z)=0,w(Z)=2。(前者小写后者大写
为了睡一个好大觉,阿宁使用了预测膜法知道 s 串,然后她可以最多使用 k 次del膜法。使用一次del膜法可以删除 s 串的一个字符。
阿宁想知道睡觉质量的最大值是多少?
链接:ac.nowcoder.com/acm/contest…
来源:牛客网
\
输入描述:
第一行输入两个正整数 n、k,表示字符串的长度和del膜法的最多使用次数。
第二行输入一个字符串 s,仅包含字符 'z' 和 'Z'。
2≤n≤2×10^5
1≤k≤2×10^5
输出描述:
一个整数,睡觉质量的最大值。
示例
输入
3 2
ZzZ
输出
4
说明
使用一次del膜法删除中间的 'z',字符串为 "ZZ",睡眠质量为 4。
问题解析
不难看出,只要两个大z之间有一个小z,那么这两个大z都是0分。
所以这题我们就是要尽可能删掉两个大z之间的所有小z,那我们就记录下两个大z之间连续的小z个数,再将它们从小到大排序,然后开始删除,删到我们无法将两个大z之间的小z删完为止。
最后根据字符串的情况来计算睡眠质量。
AC代码
#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include<math.h>
#include<set>
#include <random>
#include<numeric>
#include<string>
#include<string.h>
#include<iterator>
#include<fstream>
#include<map>
#include<unordered_map>
#include<stack>
#include<list>
#include<queue>
#include<iomanip>
#include<bitset>
//#pragma GCC optimize(3)
#define endl '\n'
#define int ll
#define PI acos(-1)
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll>PII;
const int N = 1e8 + 50, MOD = 1e9 + 7;
void solve()
{
int n,m;
string s;
cin>>n>>m>>s;
int cnt=0;
vector<int>v;
bool flag=false;
for(int i=0;i<n;i++)
{
if(s[i]=='z')cnt++;
else
{
//如果之前出现过了大Z,才记录小z的数量
if(flag)
v.push_back(cnt);
cnt=0;
}
if(s[i]=='Z')flag=true;
}
sort(v.begin(),v.end());
unordered_map<int, int>mymap;
for(auto i:v)
{
if(m-i<0)break;
mymap[i]++;
m-=i;
}
cnt=0;
string str;
flag=false;
for(int i=0;i<n;i++)
{
if(s[i]=='z')cnt++;
else
{
if(flag&&cnt!=0)
{
if(mymap[cnt]<=0)str+='z';
else mymap[cnt]--;
}
str+=s[i];
cnt=0;
}
if(s[i]=='Z')flag=true;
}
n=str.size();
int res=0;
for(int i=0;i<n-1;i++)
{
int x=(str[i]=='Z'?2:0),y=(str[i+1]=='Z'?2:0);
res+=x*y;
}
cout<<res;
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int t = 1;
//cin >> t;
while (t--)
{
solve();
}
return 0;
}