解题思路:
题目要寻找与字符串s1,s2差异度为t的字符串,我们观察发现,对于任意位置pos,若s1[pos] = s2[pos],不管ans[pos]是否与之相同,都不会导致ans与s1,s2差异度不同;
若s1[pos] != s2[pos],同样若ans[pos]与之都不同,不会产生影响,但是若ans[pos]与某字符串该位置上的字符相同(假设ans[pos]=s1[pos]),会造成差异度不相等,这时的解决办法是找到下个字符不同的位置k,另ans[k] = s2[k]. 即需要成对的选择s1[pos] != s2[pos]的字符,进行上述操作.
假设字符串s1,s2相同字符数量为same,不同字符数量为diff
1. 通过枚举选择的对数i(0<=i<=diff/2),因为对每对字符进行轮流选择操作会造成1个差异度,所以现有差异度为i;其他的不同字符造成的差异度为diff-2*i;相同字符需要造成的差异度为t-i-(diff-2*i);
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 100024;
char s1[maxn], s2[maxn];
char getdiff(char c){
for(int i=0; i<26; i++){
char t = i + 'a';
if(t != c) return t;
}
}
char getdiff(char c, char ch){
for(int i=0; i<26; i++){
char t = i + 'a';
if(t != c && t != ch) return t;
}
}
int main(){
int n, t;
scanf("%d%d",&n,&t);
scanf("%s",s1);
scanf("%s",s2);
int diff = 0, same;
for(int i=0; i<n; i++)
if(s1[i] != s2[i])
diff++;
same = n - diff;
char ans[maxn];
int k=0;
for(int i=0; i<=diff; i+=2){
int ex = i/2 + (diff-i);//字符不同区域造成的差异度
if(ex<=t && t<=ex+same){
bool f = true;
int need = t - ex; //字符相同区域不要补充的差异度
int cnt = i;
for(int j=0; j<n; j++){
if(s1[j] == s2[j]){
if(need > 0){
ans[k++] = getdiff(s1[j]);
need--;
}else ans[k++] = s1[j];
}else{
if(cnt > 0){
ans[k++] = f ? s1[j] : s2[j];
cnt--;
f = !f;
}else ans[k++] = getdiff(s1[j],s2[j]);
}
}
ans[k] = 0;
printf("%s\n",ans);
return 0;
}
}
printf("-1\n");
return 0;
}
2. 利用贪心策略解决,不同字符区域可造成差异度的范围为diff-diff/2到diff,若t在此范围内,假设x为进行轮流选择操作的对数,有x + (diff-2*x) = t,推导出x = diff-t;若大于diff,则需要从字符相同区域补充t-diff的差异度.
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 100024;
char s1[maxn], s2[maxn];
char find(char c){
int i;
for(i=0; i<26; i++){
char ch = i+'a';
if(ch != c)
return ch;
}
}
char find(char c, char s){
int i;
for(i=0; i<26; i++){
char ch = i+'a';
if(ch != c && ch!=s)
return ch;
}
}
int main(){
int n, t, diff, len=0, i;
scanf("%d%d",&n,&t);
char ans[maxn];
int k=0;
scanf("%s",s1);
scanf("%s",s2);
for(i=0; i<n; i++){
if(s1[i] == s2[i])
len++;
}
diff = n - len;
if(2*t < diff)
printf("-1\n");
else{
int cnt = diff - t;
int tmp = t - diff;
bool flag = false;
for(int i=0; i<n; i++){
if(s1[i]==s2[i]){
if(tmp > 0){
ans[k++] = find(s1[i]);
tmp--;
}else ans[k++] = s1[i];
}else{
if(cnt > 0){
if(flag){
ans[k++] = s1[i];
cnt--;
}else ans[k++] = s2[i];
flag = !flag;
}else{
ans[k++] = find(s1[i],s2[i]);
}
}
}
ans[k] = 0;
printf("%s\n",ans);
}
return 0;
}