传送门

构造一个字典序最小的字符串使得到 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距离 ab,最后 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;
	}
}