题目大意
给你两个字符串s,t由小写字母和@组成,你可以将@替换成“a" "t" "c" "o" "d" "e" "r"
替换后将两个字符串重新排列,如果能得到这两个字符串相等,那么输出Yes,否则输出No
思路
我刚开始想的是将两个排序后从头遍历到末尾记录两个字符串不一样的个数,但是后面发现排序可能会出现两个字符串 分别为acoo 和 co@@,很明显这种情况得到结果是Yes,但是如过从头遍历到尾s[0]!=t[0]……一直遍历到结束会发现不同的字符有四个而@只有两个,但实际情况应该是不同的字母有两个,很明显这样做有点问题。那我们不妨想,如果不排列直接统计字母的个数呢若两个字母的个数不同且不为atcoder其中的任意一个,那么即使有@也不能替换,得到的结果就是”No",如果a在s字符串中出现了3次,而在t字符串中出现了1次,那么我们就认为不同的次数为 differ = 3 - 1;。那么是怎么统计字母的个数呢?我们可以将26个字母映射到0~25这个区间内,然后将@映射为26
具体代码如下
bool pd(string s, string t)
{
int len = s.size();
int _s[27] = { 0 }, _t[27] = { 0 };
for (int i = 0; i < len; i++)
{
if(s[i]!='@')
{
_s[s[i] - 'a']++;
}
if (t[i] != '@')
_t[t[i] - 'a']++;
if (s[i] == '@')
_s[26]++;
if (t[i] == '@')
_t[26]++;
}
int differ=0;
for (int i = 0; i < 26; i++)
{
if (_s[i] != _t[i])
{
if (i != 0 && i != 19 && i != 2 && i != 14 && i != 3 && i != 4 && i != 17)
return false;
else
differ+=abs(_s[i]-_t[i]);
}
}
if (differ <=_s[26]+_t[26])
return true;
else
return false;
}
完整代码如下
#include<iostream>
using namespace std;
bool pd(string s, string t)
{
int len = s.size();
int _s[150] = { 0 }, _t[150] = { 0 };
for (int i = 0; i < len; i++)
{
if(s[i]!='@')
{
_s[s[i] - 'a']++;
}
if (t[i] != '@')
_t[t[i] - 'a']++;
if (s[i] == '@')
_s[26]++;
if (t[i] == '@')
_t[26]++;
}
int differ=0;
for (int i = 0; i < 26; i++)
{
if (_s[i] != _t[i])
{
if (i != 0 && i != 19 && i != 2 && i != 14 && i != 3 && i != 4 && i != 17)
return false;
else
differ+=abs(_s[i]-_t[i]);
}
}
if (differ <=max(_s[26],_t[26]))
return true;
else
return false;
}
int main()
{
string s, t;
cin >> s;
cin >> t;
if (pd(s, t)==true)
cout << "Yes";
else
cout << "No";
}