P7050题解
这题我们先观察样例。
显然,
可是如果按照上面的方法计算,样例二因该输出
我们来看看它们所构成的字符串。
tp trp trep treep
tap trap treap treeap
teap treap treeap treeeap
theap trheap treheap treeheap
我们可以发现第二行和第三行有两个词重复了,如果减去这两个词的话答案就正确了。
所以,答案
两个长度好求,但重复的数量怎么求呢?
首先,我们可以想到用 map 容器。
于是,我们可以写出下面的代码。
#include<iostream>
#include<map>
using namespace std;
map<string,bool> t;
int main(){
string a,b;
cin>>a>>b;
for(int i=1;i<=a.size();i++){
for(int j=0;j<b.size();j++) {
string c=a.substr(0,i)+b.substr(j);
t[c]=1;
}
}
cout<<t.size();
}
MLE 了。
那我们想想还有什么方法可以得到重复的数量。
再次观察样例二后发现,重复的数量就是两个单词的相同字母数量之积。
为什么每出现一个相同的字母,就会有重复的单词出现呢?
就拿 tree 和 heap 证明一下:
可见,两个词中重复的字母是可以构成的重复词为:
treap 和 treeap
我们在设
可得
其中
所以,我们只需要开两个数组分别记录两个字符串中每个字母的出现次数,然后计算出有多少重复的字母就好了。
ACCODE
#include<bits/stdc++.h>
using namespace std;
long long sum,ans,a[60],b[60];
string s,s1;
int main()
{
cin >> s >> s1;
ans = s.size() * s1.size();
for(int i = 1;i < s.size();i++) a[s[i] - 'a']++;
for(int i = 0;i < s1.size() - 1;i++) b[s1[i] - 'a']++;
for(int i = 0;i < 26;i++) sum += a[i] * b[i];
printf("%lld",ans - sum);
return 0;
}