知识点:枚举+查表
题目表述:
定一个由小写字母构成的字符串 S。
再给定一个由若干个各不相同的小写字母按字典序排序构成的字符串 FF。
现在,你可以对字符串 S 进行字符转换操作。
每次选中其中一个字符(即某个小写字母),将其转换为一个按照字母顺序与其相邻(上一个或下一个)的小写字母。
例如,c 可以转换为 b 或 d。
额外的,我们将按照循环顺序考虑字母,即我们认为 a 的上一个字母为z,z 的下一个字母为 a。
请问,至少需要进行多少次操作,可以使得字符串 S 中的每个字母都出现在字符串 FF 中。
输入格式
第一行包含整数 T,表示共有 T 组测试数据。
每组数据第一行包含一个字符串 S。
第二行包含一个字符串 F。
输出格式
每组数据输出一个结果,每个结果占一行。
结果表示为 Case #x: y
,其中 x 为组别编号(从 11 开始),y 为最少操作次数。
可以发现字母之间的所有变换是围成一个圈的。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int st[30];
int cnt[30];
int main()
{
int t;
cin>>t;
for(int cases=1;cases<=t;cases++){
string s,f;
cin>>s;
cin>>f;
for(int i=0;i<f.size();i++){
st[f[i]-'a']=1;
}
for(int i=0;i<26;i++){
int l = 0,r = 0;//左右指针
while( !st[(i+r)%26] ) r++;
while( !st[(i-l+26)%26] ) l++;
cnt[i]=min(l,r);
}
int ans=0;
for(int i=0;i<s.size();i++){
ans+=cnt[s[i]-'a'];
}
printf("Case #%d: %d\n",cases,ans);
}
return 0;
}
求所有的26个小写字母到字符串f中的每个小写字母的距离(变换次数),分别往左右两边去算,然后比较哪一边的距离最短,也就是变换次数最少。
然后再进行查表,查出所有目标字母