[题解]CF1800B Count the Number of Pairs
题意
给定一个字符串 \(S\),你可以进行 \(k\) 次操作,每次操作你可以选定一个 \(i\),并将 \(S_i\) 的大小写转换。
求:操作后,最多有几组配对的字符。(配对的定义是:对于一个字符,如果有大写,有小写被称之为一组。例如:A 和 a 为一组。)
思路
你在读入的时候,你预处理一个数组 \(vis_{c,0/1}\) 表示,\(c\) 这个字符的大写/小写出现的次数。
然后,你就暴力判断 \(|vis_{s_i,0} - vis_{s_i,1}|\) 是否大于 \(1\),如果大于 \(1\) 才有变换的意义;否则直接将答案加上它。
对于每一次变换,你判断一下 \(\lfloor \frac{|vis_{s_i,0} - vis_{s_i,1}|}{2} \rfloor\) 和当前 \(k\) 的关系,然后加答案即可。
Code
#include <bits/stdc++.h>
#define re register
using namespace std;
const int N = 27;
int T,n,k,ans;
int vis[N][2];
string s;
inline int get(char c){
if (c >= 'A' && c <= 'Z') return c - 'A' + 1;
return c - 'a' + 1;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while (T--){
memset(vis,0,sizeof(vis));
cin >> n >> k >> s;
ans = 0;
s = ' ' + s;
for (re int i = 1;i <= n;i++){
if (s[i] >= 'A' && s[i] <= 'Z') vis[get(s[i])][0]++;//统计
else vis[get(s[i])][1]++;
}
for (re int i = 1;i <= 26;i++){
int t = abs(vis[i][0] - vis[i][1]);
if (t <= 1) ans += min(vis[i][0],vis[i][1]);//判断是否要进行变换
else{
int cnt = t >> 1;
if (cnt <= k){//如果要变换的次数小于等于 k 就可以全部变换
ans += min(vis[i][0],vis[i][1]) + cnt;
k -= cnt;
}
else{//否则,只能变换 k 次
ans += min(vis[i][0],vis[i][1]) + k;
k = 0;
}
}
}
printf("%d\n",ans);
}
return 0;
}

浙公网安备 33010602011771号