题目已经给出了提示,用哈希求解。
解题思路就是枚举每个字符串的的子串,计算其哈希值,存在set中(去重),然后再将各个哈希值的出现次数存储在map中。
最后,遍历map,并累计。最后的结果应减去cas数,即减去自己对自己的密码。
#include <bits/stdc++.h>
typedef long long int ll;
#define PI 3.14159265358979323846
#define INF 0x3f3f3f3f
#define INFLL 0x3f3f3f3f3f3f3f3fll
#define maxn 1000+10
#define mod 2000120420010122
using namespace std;
inline ll getHash(string s){//网上学习的哈希函数,听说这个函数的分布比较均匀,get
ll hash=0;
for(int i=0;i<s.length();i++){
hash=s[i] + (hash<<6) + (hash<<16) - hash;
}
return hash;
}
void solve(){
int cas;
cin>>cas;
string password[cas];
for(int i=0;i<cas;i++){
cin>>password[i];
}
map<ll,ll> ma;
for(int i=0;i<cas;i++){
set<ll> se;
int len=(int)password[i].length();
string affect=password[i];
for(int l=1;l<=len;l++){
for(int j=0;j<len-l+1;j++){
string tmp="";
for(int k=0;k<l;k++){
tmp+=affect[j+k];
}
ll hash=getHash(tmp);
se.insert(hash);
}
}
for(ll hash : se){
ma[hash]++;
}
}
ll cnt=0;
for(int i=0;i<cas;i++){
cnt += ma[getHash(password[i])];
}
cout<<cnt - cas<<endl;
}
int main(int argc, char const *argv[]){
solve();
return 0;
}