问题 H: Hamming Distance
时间限制: 1 Sec 内存限制: 128 MB
提交: 246 解决: 41
[提交] [状态] [命题人:admin]
题目描述
In information theory, the Hamming distance between two strings of equal length is the number of positions at which the corresponding symbols are different. In other words, it measures the minimum number of substitutions required to change one string into the other, or the minimum number of errors that could have transformed one string into the other.– Wikipedia
Assume that there are two strings with same length, which only contain lowercase characters, find a lexicographically smallest string with same length, and the Hamming distance between the target string and each original string are equal.
输入
The first line contains a number T (1≤T≤100), indicating the number of test cases.
Each time case contains two lines of strings, indicating the two original strings, which only contain lowercase characters. The length of string is smaller than 104, and total length of the strings is less then 106.
输出
For each case, output "Case x: y in which x indicates the case number starting with 1, and y indicates the result of the target string. The target string should only contain lowercase characters.
样例输入
复制样例数据
2 abc acd abandon newyork
样例输出
Case 1: aaa Case 2: aaaaark
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define lowb(i) (i&(-i))
#define N 1000005
#define inf 0x3f3f3f3f
#define maxn 20005
#define pb(x) push_back(x)
#define Sca(x) scanf("%lld",&x)
#define sca(x) scanf("%d",&x)
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
char s[N],s1[N],s2[N];
int len;
void solve(int del)
{
for(int i=1; i<=len; i++)s2[i]='a';
if(del<0)del=-del,swap(s,s1);
int num=0,del1=del;
int i;
for(i=len; i>=1; i--)
{
if(s[i]==s1[i])continue;
if(s[i]=='a')num+=2;
else if(s1[i]!='a')num++;
if(s[i]=='a')
{
if(del>=2)del-=2;
else del--;
}
else if(s1[i]!='a')del--;
if(del==0)break;
}
for(i;i<=len;i++)
{
if(del1>0)
{
if(s[i]==s1[i])continue;
if(s[i]=='a')num-=2;
else if(s1[i]!='a')num--;
if(s[i]=='a')
{
if(s1[i]=='b')
{
if(del1>=2)
{
del1-=2;
s2[i]='b';
}
else
{
if(del1)
{
s2[i]='c';
del1--;
}
}
}
else
{
if(del1-1>num)
{
s2[i]=s1[i];
del1-=2;
}
else
{
if(del1)
{
s2[i]='b';
del1--;
}
}
}
}
else if(s1[i]!='a'&&del1>0)
{
s2[i]=s1[i];
del1--;
}
}
}
s2[len+1]='\0';
puts(s2+1);
}
int main()
{
int t;
sca(t);
int cas=1;
while(t--)
{
scanf("%s%s",s+1,s1+1);
len=strlen(s+1);
int sum1=0,sum2=0;
for(int i=1; i<=len; i++)
{
if(s[i]=='a')sum1++;
if(s1[i]=='a')sum2++;
}
int del=sum1-sum2;
printf("Case %d: ",cas++);
if(del==0)
{
for(int i=1; i<=len; i++)
{
printf("a");
}
printf("\n");
continue;
}
else solve(del);
}
}
/*
aaca
bbdb
ans=aadb
aaa
bbb
acb
ans=abc
a
b
c
d
总结:
首先要找到最少的要修改的位置。
1.如果两个位置相等则无需改变。
2.如果第一个串的当前字符为a
讨论另一个字符:
如果另一个字符为b
则把当前字符改成b会使得del-=2,否则的话就改成c(根据del的大小);
如果另一个字符不是b
则把当前字符改成b会使del-1,此时可能会产生这样一种情况(无论后边怎么改变都不会使del为0)。
所以会产生当前位置不能改成b的情况。分离出这种情况。
分离出这种情况的办法是维护一个num表示到当前位置最多能使del减少多少。
*/