POJ1200(hash)

Crazy Search

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 27536   Accepted: 7692

Description

Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given text. Such number could be the number of different substrings of a given size that exist in the text. As you soon will discover, you really need the help of a computer and a good algorithm to solve such a puzzle. 
Your task is to write a program that given the size, N, of the substring, the number of different characters that may occur in the text, NC, and the text itself, determines the number of different substrings of size N that appear in the text.

As an example, consider N=3, NC=4 and the text "daababac". The different substrings of size 3 that can be found in this text are: "daa"; "aab"; "aba"; "bab"; "bac". Therefore, the answer should be 5.

Input

The first line of input consists of two numbers, N and NC, separated by exactly one space. This is followed by the text where the search takes place. You may assume that the maximum number of substrings formed by the possible set of characters does not exceed 16 Millions.

Output

The program should output just an integer corresponding to the number of different substrings of size N found in the given text.

Sample Input

3 4
daababac

Sample Output

5

Hint

Huge input,scanf is recommended.

思路:把长度为n的子串hash成nc进制数,避免了冲突。

 1 //2016.9.4
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #define N 16000005
 6
 7 using namespace std;
 8
 9 char str[N];
10 bool Hash[N];
11 int id[500];
12
13 int main()
14 {
15     int n, nc, ans, cnt;
16     while(scanf("%d%d", &n, &nc)!=EOF)
17     {
18         cnt = ans = 0;
19         memset(Hash, false, sizeof(Hash));
20         memset(id, -1, sizeof(id));
21         scanf("%s", str);
22         int len = strlen(str);
23         for(int i = 0; i < len && cnt < nc; i++)//对str出现的字符进行编号,使之转换成数字
24         {
25             if(id[str[i]] != -1)continue;
26             id[str[i]] = cnt++;
27         }
28         for(int i = 0; i < len-n+1; i++)//把长度为n的子串hash成nc进制数
29         {
30             int tmp = 0;
31             for(int j = i; j < i+n; j++)
32                 tmp = tmp*nc+id[str[j]];
33             if(Hash[tmp])continue;
34             ans++;
35             Hash[tmp] = true;
36         }
37         printf("%d\n", ans);
38     }
39
40     return 0;
41 }
时间: 2024-10-09 10:53:17

POJ1200(hash)的相关文章

POJ-1200 Crazy Search(hash)

Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27336   Accepted: 7641 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a gi

[poj1200]Crazy Search(hash)

Crazy Search Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26713 Accepted: 7449 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a given

poj1200 字符串hash 滚动哈希初探

假如要判断字符串A"AABA"是否是字符串B"AABAACAADAABAABA"的子串 最朴素的算法是枚举B的所有长度为4的子串,然后逐个与A进行对比,这样的时间复杂度是O(mn),m为A的长度,n为B的长度. 另一个做法是用哈希函数计算出A的哈希值,然后计算出B所有长度为4的子串的哈希值,这样比较就可以判断出A是否在B中.虽然这样做的时间复杂度还是O(mn),但是为接下来的滚动哈希打下了基础. Rabin-Karp算法采用了一种叫做滚动哈希的技巧,对哈希函数的类型

Poj1200题解

题意:给定模式字串长度和不同字符的个数,求一个长字符串的不同子串的个数 分析:刚开始做这个题目的时候,本来是想直接用HashSet做的,但是觉得一是不太可能这么水,二是可能空间也不一定够,所以就想啊想,想偏了.后来在discuss里面看到有直接用HashMap等水过的,我就试了试,还真能过.不过这种做法效率不高,实现也不难,所以就不说了. 另一种真正用上所有条件的方法就是Rabin-Karp算法做.通过将不同的字符表示成以d为进制数的d个数字,将每一个字符串表示成一个多位d进制的数t,对比不同字

HDOJ--4821--String【弦hash】

联系:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给一个字符串,选m个长度为l的子串组成新的串.要求这m个子串互不同样,问有多少种组合. 字符串hash题目,曾经没做过,做这道之前还用bkdrhash做了两道简单的题目.POJ1200和HDU1800. 用base数组记录乘了几个seed,base[i]表示seed^i,这个数组在之后计算子串hash值的时候会用到,先预处理一遍节省时间. 假设字符串从前往后hash.则hash[ i ] -

HDOJ--4821--String【字符串hash】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4821 题意:给一个字符串,选m个长度为l的子串组成新的串,要求这m个子串互不相同,问有多少种组合. 字符串hash题目,以前没做过,做这道之前还用bkdrhash做了两道简单的题目,POJ1200和HDU1800. 用base数组记录乘了几个seed,base[i]表示seed^i,这个数组在之后计算子串hash值的时候会用到,先预处理一遍节省时间. 如果字符串从前往后hash,则hash[ i ] -

poj 1200 --- 不错的字符串HASH构造方法

题目:http://poj.org/problem?id=1200 题意:给一个字符串,给定n和nc,字符串里最多有nc个不同的字符,问长度为n的不同子串最多有几个 和上一篇现场赛那个一样,也是难在判重处理不好会超时 方法:将长度为n的子串映射为一个nc进制的数,开一个大数组,判断是否重复 #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include

一致性hash算法 - consistent hashing

1.背景 我们都知道memcached服务器是不提供分布式功能的,memcached的分布式完全是由客户端来实现的.在部署memcached服务器集群时,我们需要把缓存请求尽可能分散到不同的缓存服务器中,这样可以使得所有的缓存空间都得到利用,而且可以降低单独一台缓存服务器的压力.     最简单的一种实现是,缓存请求时通过计算key的哈希值,取模后映射到不同的memcahed服务器.这种简单的实现在不考虑集群机器动态变化的情况下也是比较有效的一种方案,但是,在分布式集群系统中,简单取模的哈希算法

BZOJ3198 SDOI2013 spring HASH+容斥原理

题意:给定6个长度为n的数列,求有多少个数对(i,j)((i,j)≡(j,i))使得i和j位置恰好有K个数相同,其中0≤K≤6 题解: 设fi=至少有K个数相同的位置对的数量,用2^6枚举每一种可能,根据容斥原理,答案就是\[\sum\limits_{i = K}^N {{f_i}C_i^K{{\left( { - 1} \right)}^{i - K}}} \] 至于多乘一个组合数,是因为当前枚举到有x个数相同,一个位置对有i个相同的数,那么累计的时候就会算成$C_x^i$,因此实际上这个位置