P3370 【模板】字符串哈希

题目描述

如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。
友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)
输入输出格式
输入格式:

第一行包含一个整数N,为字符串的个数。

接下来N行每行包含一个字符串,为所提供的字符串。

输出格式:

输出包含一行,包含一个整数,为不同的字符串个数。

输入输出样例
输入样例#1:

5
abc
aaaa
abc
abcc
12345

输出样例#1:

4

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,Mi≈6,Mmax<=15;

对于70%的数据:N<=1000,Mi≈100,Mmax<=150

对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

样例说明:

样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。

Tip: 感兴趣的话,你们可以先看一看以下三题:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^_^

典型的字符串哈希

#include
#include
#include                                            //一坨头文件
using namespace std;
int n,ans=0,cnt=0;
string a,data[10007];
int list[10001]={0};
int next[10001]={0};
int ok(string h)
{
    int sum=0;
    for(int i=0;i33+h[i];                   //将字符串转化为数字再来hash。。。
    sum=abs(sum%10007);                                         //照常膜蛤。。。就是注意要abs,因为sum是int类型,字符串一长就会爆成负数,不过没事,不会让程序出错。。。只要不是负数就可以了。。。
    int u=list[sum];
    while(u)
    {
        if(data[u]==h)return 0;                          //判断前面是否有相同的字符串。。
        u=next[u];
    }
    cnt++;
    data[cnt]=h;
    next[cnt]=list[sum];
    list[sum]=cnt;                                              //如果sum所在的位置有东西,就要把它“吊”在下面。。。(就是类似链表的东西)
    return 1;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a;
        if(ok(a))ans++;                                   //如果没有重复就ans++
    }
    cout<//输出
    return 0;                                                 //回家
}

你可能感兴趣的:(字符串)