题目:古老的密码
题目描述:
给定两个长度一样且不超过100的字符串,判断是否能把其中一个字符串的各个字母重排,之后对26个字母做一个一一映射,使得两个字符串相同
例如,JWPUDJSTVP重排后可以得到WJDUPSJPVT,之后把每个字母映射到它的前面一个字母,得到VICTORIOUS,输入两个字符串,输出YES或者NO
题目分析:
因为字母可以重排,每个字母的位置并不重要,重要的是每个字母出现的次数
①统计两个字符串每个字母出现的次数,得到两个数组cnt1[26],cnt2[26]
②之后我们排序下,排序之后结果相同,说明我们输入的两个字符串就可以通过重排一一映射变得相同了所以本道题的核心在与【排序】
(可以理解为映射可以有无穷多种方式,但是无论哪一种方式同一个字符的映射方式是相同的,所以要想映射结果相同,那么两字符串中相同字符的数量必然要相同)
实现:
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int cmp(int a, int b)
{
return a < b;
}
int main()
{
string s,t;
int cnt1[26], cnt2[26];
while(cin >> s >> t){
int len = s.length();
memset(cnt1, 0, sizeof(cnt1));
memset(cnt2, 0, sizeof(cnt2));
for(int i = 0; i < len; i++){
cnt1[s[i]-'A']++; //统计不同字符数量 巧妙
cnt2[t[i]-'A']++;
}
sort(cnt1, cnt1+26, cmp);
sort(cnt2, cnt2+26, cmp);
int flag = 1;
for(int i = 0; i < 26; i++ ){
if(cnt1[i] != cnt2[i]){
flag = 0;
break;
}
}
if(flag == 1)
cout <<"YES\n";
else
cout <<"NO\n";
}
return 0;
}