题意:
用前k个大写字母,替代原来字符串的大写字母,使得两两相邻的字母不一样。要求使用最少的替代次数。
思路:
因为是在dp专题里看到,所以一直想dp的做法,后来实在不知道应该怎么搞。
于是乎看了下别人的思路。
k > 2:直接模拟枚举下去。每个位置与两旁的字母比较,相同就改,做到不与左右相同即可。(证明不会= =,应该是贪心吧)
k = 2:只有两种情况,ABABA……,BABABA……哪种改动次数少选哪种。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 5*1e5+5;
const int INF = 0x3f3f3f3f;
int n, k;
char ch[MAXN];
char tt[MAXN];
void spdeal() {
int len = strlen(ch);
strcpy(tt, ch);
int t = 0;
int res = 0;
for(int i = 0;i < len; i++) {
if(ch[i] != t+'A') {
ch[i] = t+'A';
res ++;
}
t ^= 1;
}
int res2 = 0;
t = 1;
for(int i = 0;i < len; i++) {
if(tt[i] != t+'A') {
tt[i] = t+'A';
res2++;
}
t ^= 1;
}
printf("%d\n", min(res, res2));
if(res < res2)
printf("%s\n", ch);
else
printf("%s\n", tt);
}
void solve() {
if(k == 2) {
spdeal();
return;
}
int len = strlen(ch);
int res = 0;
for(int i = 1;i < len; i++) {
if(i == len-1) {
if(ch[i-1] == ch[i]) {
for(int t = 0;t < k; t++)
if(t+'A' != ch[i-1]) {
res++;
ch[i] = t+'A';
break;
}
}
} else {
if(ch[i-1]==ch[i]) {
for(int t = 0;t < k; t++) {
char tmp = t+'A';
if(tmp != ch[i-1] && tmp != ch[i+1]) {
res++;
ch[i] = tmp;
break;
}
}
}
}
}
printf("%d\n", res);
printf("%s\n", ch);
}
int main() {
scanf("%d%d", &n, &k);
scanf("%s", ch);
solve();
return 0;
}