构造一个字典序最小的字符串使得到 a , b a,b a,b两串的汉明距离相等。
很明显大多数时候填 ′ a ′ 'a' ′a′会比较优秀
因为字典序的比较关系,只要这一位能填 ′ a ′ 'a' ′a′,我们就应该无脑填 ′ a ′ 'a' ′a′
我们记 n o w d i s nowdis nowdis为 a 距 离 − b 距 离 a距离-b距离 a距离−b距离,最后 n o w d i s nowdis nowdis应该是 0 0 0
明显当 a , b a,b a,b串字母相同时,本位不管放什么都不会影响 n o w d i s nowdis nowdis
当 a , b a,b a,b串不同时,我既可以让 n o w d i s nowdis nowdis不变,也可以 n o w d i s + + nowdis++ nowdis++,也可以 n o w d i s − − nowdis-- nowdis−−
所以这就是 n o w d i s nowdis nowdis的松弛度,即为后缀中不同字母的数量
只要后缀字母的松弛度大于等于 a b s ( n o w d i s ) abs(nowdis) abs(nowdis),我就放 ′ a ′ 'a' ′a′
代码中其实也就是枚举每一个字母放而已
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int t,n,casenum,f[maxn],nowdis;
char a[maxn],b[maxn];
bool isok(char w,int index )
{
int now = nowdis;
if( w!=a[index] ) now++;
if( w!=b[index] ) now--;
return abs(now)<=f[index+1];
}
int main()
{
cin >> t;
while( t-- )
{
scanf("%s%s",a+1,b+1 );
n = strlen( a+1 );
f[n+1] = 0;
for(int i=n;i>=1;i--)
{
f[i] = f[i+1];
if( a[i]!=b[i] ) f[i]++;
}
cout << "Case " << ++casenum << ": ";
nowdis = 0;//目前(a距离-b距离)的
for(int i=1;i<=n;i++)
{
for(char w='a';w<='z';w++)
{
if( !isok(w,i) ) continue;
printf("%c",w);
if( w!=a[i] ) nowdis++;
if( w!=b[i] ) nowdis--;
break;
}
}
cout << endl;
}
}