gym102823-problem-H - Hamming Distance

链接:

https://codeforces.ml/gym/102823/problem/H

题意:

HM(a,b)表示字符串a和b的汉明距离,定义两个字符串不同点的数量

给两个字符串a,b,求构建一个满足HM(a,c)=HM(b,c)的最小字典序C

解:

2018CCPC的桂林H题

前段时间摸了一下虚拟赛,确确实实是蒟蒻了

当时是和思路找a和b中字符’a’的数量,然后根据数量差,前面全填’a’,从后面开始修改对应数量差的字符(然后卡死了,处理没写出来)

这边补一下这题=-=

如果ai和bi是相同的话,那么无论ci是什么字符,他们的汉明值[HM(a,c)和HM(b,c)]都不会变

如果ci不和ai、bi相同的话他们的汉明值也不会变

但是,如过ai和bi在这个位置不相同,且我们让ci和其中一个相同,就能影响一点汉明值

那么,我们以后缀和的方式标记两个串每个后置后面的不同的位置的数量(为什么呢)

为了字典序最小,我们从最前面开始填充,直接遍历’a’到’z’(实际上,只要判断4个字符,‘a’,ai,bi和除了ai,bi离’a’最近的字符)

设置一开始的汉明差[HM(a,c)-HM(b,c)]为0,那么如果我们填充字符和a不同,汉明差就加一,和b不同,汉明差减一

那么在这个点上的前缀汉明差,要大于等于后后缀的不同的位置的数量,这样就能保住我填入这个字符,而后面是有办法使之合法

即通过等于ai或者ci来调整汉明差(字典序最小所以优先前面填小的)

那么为什么不能拿汉明差和整段的不同的位置的数量进行比较呢,因为如果对于这个位置上的不同字符,我填与之都不相同的字符,那么这个位置及前面的汉明差是不变的,但是这个位置已经填完了失去了调整汉明差的作用!

实际代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#define csh(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long int ll;
const int Size=1E6+5;
int sz[Size];
string a,b;
char tc(int change,int i)
{
	for(char ch='a';ch<='z';ch++)
	{
		int tempHM=change;
		if(ch!=a[i]) tempHM++;//填充这个字母和a串对于字母不同,HM(a)增加
		if(ch!=b[i]) tempHM--;//填充这个字母和b串对于字母不同,HM(b)增加
		if(abs(tempHM) <= sz[i+1])//可以修正
		{
			return ch;
		}
	}
}
int main()
{
	int T;
	cin>>T;
	for(int f=1;f<=T;f++)
	{
		cin>>a>>b;
		int lg=a.length();
		sz[lg]=0;
		for(int i=lg-1;i>=0;i--)
		{
			sz[i]=sz[i+1];
			if(a[i]!=b[i]) sz[i]++;//后缀不相等量
			//如果相同,那么那个位置上不论放置什么字符 HM(a)和HM(b)都不会受到影响 
			//那么,每一个不同之处,都能让修正前面的HM差 
		}
		int change=0;//目前情况下对于a,b的HM差,定为HM(a)-HM(b); 
		cout<<"Case "<<f<<": ";//案例标记 
		for(int i=0;i<lg;i++)
		{
			char c=tc(change,i);
			cout<<c;
			if(c!=a[i])	change++;//修改前面的HM差标记 
			if(c!=b[i])	change--;
		}
		cout<<endl;
	}
}

限制:

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值