Skip to main content
  1. Posts/

poj 1200 Crazy Search (字符串哈希)

·1 min
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

题目链接

题意:一个字符串,其仅由nc种字符组成,问其所有长度为n的字串里,共用多少种不同的。

思路:一开始木有懂nc种字符有什么用…

然后写了hash,发现会TLE。。。因为用到了map,被卡了个log..

nc的作用是,可以把字符串看成一个nc进制的数,这样做的好处是,得到的hash值可以尽可能的小而且保证了不同的字符串对应了不同的hash值。

然后就可以不用map而是一个数组,就变成了O(1)赋值和判断了。。。

(然而没有数据范围其实还是有点耍流氓的嫌疑。。

 1#include <iostream>
 2#include <cstring>
 3#include <stdio.h>
 4using namespace std;
 5const int N=16000005; //题目给出子串的最大和不超过16M
 6const int NUM=257;
 7bool Hash[N];
 8int m[NUM];
 9char str[1000000];
10
11int n,nc,i,j,sum,seed=0,ans=0;
12int main()
13{
14  //  freopen("code/in.txt","r",stdin);
15    memset(Hash,false,sizeof(Hash));
16    memset(m,0,sizeof(m));
17    memset(str,'\0',sizeof(str));
18    cin>>n>>nc>>str;
19    int len = strlen(str);
20    for(int i = 0 ; i < len; ++i)
21    {
22        if(!m[str[i]]) //将每个字符赋值为相应进制的数
23            m[str[i]]=++seed;
24        if(seed == nc)
25            break;
26    }
27    for(i=0;i<=len-n;++i)
28    {
29        sum=0;
30        for(j=0;j<n;++j) //将字符串str[i],..,str[i+n-1]变为一个nc进制的整数,来判断是否重复出现过
31            sum=sum*nc+m[str[i+j]]-1;
32
33        if(!Hash[sum])
34        {
35            Hash[sum]=true;
36            ++ans;
37        }
38    }
39    cout<<ans<<endl;
40    return 0;
41}

Related

hdu 1800 Flying to the Mars (字符串hash)

·2 mins
题目链接 题意:n个人,每个人有一个level值,用一个最长30位的,可能带前缀0的数字串表示,如果i的level大于j的level,那么i可以教j飞行,每个人只能有一个老师,每个人也只能收一个徒弟。师生可以共用一把扫帚飞行。现在问最少需要多少扫帚。

codeforces 4C. Registration system (字符串hash)

·1 min
题目链接 题意:网站的注册系统..处理用户要注册的用户名,如果数据库中没有重名输出OK,否则输出要注册的用户名的字符串+num,num的大小为之前一共有多少个用户试图用该用户名。

hdu 1880 魔咒词典 (字符串hash)

·1 min
题目链接 题意:给你一部魔咒词典。当哈利听到一个魔咒时,你的程序必须告诉他那个魔咒的功能;当哈利需要某个功能但不知道该用什么魔咒时,你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中,就输出“what?”