字 符 串 哈 希 字符串哈希 字符串哈希
题目链接:luogu P3370
题目
如题,给定 N N N个字符串(第 i i i个字符串长度为 M i Mi Mi,字符串内包含数字、大小写字母,大小写敏感),请求出 N N N个字符串中共有多少个不同的字符串。
输入
第一行包含一个整数
N
N
N,为字符串的个数。
接下来
N
N
N行每行包含一个字符串,为所提供的字符串。
输出
输出包含一行,包含一个整数,为不同的字符串个数。
样例输入
5
abc
aaaa
abc
abcc
12345
样例输出
4
样例解释
样例中第一个字符串 ( a b c ) (abc) (abc)和第三个字符串 ( a b c ) (abc) (abc)是一样的,所以所提供字符串的集合为 { a a a a , a b c , a b c c , 12345 } \{aaaa,abc,abcc,12345\} {aaaa,abc,abcc,12345},故共计 4 4 4个不同的字符串。
数据范围
对于
30
%
30\%
30%的数据:
N
<
=
10
,
M
i
≈
6
,
M
m
a
x
<
=
15
N<=10,Mi≈6,Mmax<=15
N<=10,Mi≈6,Mmax<=15;
对于
70
%
70\%
70%的数据:
N
<
=
1000
,
M
i
≈
100
,
M
m
a
x
<
=
150
N<=1000,Mi≈100,Mmax<=150
N<=1000,Mi≈100,Mmax<=150
对于
100
%
100\%
100%的数据:
N
<
=
10000
,
M
i
≈
1000
,
M
m
a
x
<
=
1500
N<=10000,Mi≈1000,Mmax<=1500
N<=10000,Mi≈1000,Mmax<=1500
思路
这道题就是字符串Hash的模板,没什么好说的。
代码
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
ll n, a, f[10001], p = 67, len, ans;
char b[1001];
ll qsm(ll i, ll j) {//快速幂
ll an = 1;
while (j) {
if (j & 1) an = an * i;
i = i * i;
j >>= 1;
}
return an;
}
ll hs(ll i) {//哈希
if (b[i] >= '0' && b[i] <= '9') return (b[i] - 48) * qsm(p, i);
if (b[i] >= 'A' && b[i] <= 'Z') return (b[i] - 55) * qsm(p, i);
return (b[i] - 61) * qsm(p, i);
}
int main() {
scanf("%lld", &n);//读入
for (ll i = 1; i <= n; i++) {
getchar();//处理换行符
scanf("%s", &b);//读入
len = strlen(b);//求出字符串长度
a = 0;//初始化
for (ll i = 0;i < len; i++)
a += hs(i);//求出此字符串的哈希值
bool yes = 0;//初始化
for (ll i = 1; i <= ans; i++)
if (a == f[i]) {//判断是否与前面的字符串有相同的
yes = 1;//标记
break;//退出
}
if (!yes) {//是否是新的字符串
ans++;//不同的字符串数增加
f[ans] = a;//记录下来
}
}
printf("%lld", ans);//输出
return 0;
}