[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 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的字符串,其中字符集大小不超过nc,求其中不同的子串个数

第一不要dp做多了把子串看成不连续的

子串就是源字符串连续的子序列!这点看题解才发现……想了半天也想不出来

接下来就好办多了,枚举每一位即可

但问题又来了,如何去重?kmp不行,ac自动机没试过不会,但目测仍然超时

接下来由rk-hash实力打脸kmp!

o(len)的速度没的说,而且已知hash值的话只用o(1)就能办到

rk-hash是什么?把字符串看成一个整数的高精度即可(请自行百度)

但算出哈希还不够,hash值应该会很大,所以要再用一次哈希,模一个素数,模拟链表处理冲突

这样大概空间时间就差不多了

但!but!

“字符集大小”并不意味着按照abcde的顺序给出!

所以单个字符对应的hash值还得自己做出来(具体看代码)

1 //子串还必须是连续的(不然无解了)
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 int base,len;
 6 const int mod=100007;
 7 char read[16000000];
 8 int ex[128]={0};//单个字符值
 9 int hash[mod+1][100]={{0}};
10 int get(int pos){
11     int ans=0;
12     for(int i=pos;i<pos+len;i++){
13         ans*=base;
14         ans+=ex[read[i]];
15     }
16     int tmp=ans%mod;
17     if(hash[tmp][0])for(int i=1;i<=hash[tmp][0];i++)if(hash[tmp][i]==ans)return 0;
18     hash[tmp][0]++;
19      hash[tmp][hash[tmp][0]]=ans;
20      return 1;
21 }
22 int main(){
23     scanf("%d %d\n%s",&len,&base,read);
24     int le=strlen(read);
25     for(int i=0,j=0;i<le;i++){
26         if(!ex[read[i]])ex[read[i]]=++j;
27         if(j==base)break;//很简洁地处理字符对应关系
28     }
29     int ans=0;
30     for(int i=0;i<=le-len;i++)ans+=get(i);
31     printf("%d\n",ans);
32     return 0;

33 }

时间: 2024-10-02 23:13:56

[poj1200]Crazy Search(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

hdu1381 Crazy Search(hash map)

题目意思: 给出一个字符串和字串的长度,求出该字符串的所有给定长度的字串的个数(不相同). 题目分析: 此题为简单的字符串哈hash map问题,可以直接调用STL里的map类.map<string,int> snum; AC代码: #include<iostream> #include<string> #include<map> using namespace std; int main() { int t,n,nc; cin>>t; whil

POJ 1200 Crazy Search(Hash)

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 t

POJ 1200 Crazy Search (字符串hash)

题目大意: 分析长度为n的子串有多少种. 思路分析: 对于没出现的字符,将其分配一个数字. 然后将子串看做一个nc进制的数. 然后hash判断. #include <cstdio> #include <iostream> #include <algorithm> #include <map> #include <cstring> #include <string> using namespace std; bool vis[26666

Crazy Search

poj1200:http://poj.org/problem?id=1200 题意:给你一个有m种字符串,求长度为n的连续子串由多少种. 题解:网上的代码都是hash,但是本人觉得hash有问题,就是n,m稍微大点,hash的值都会爆出int,无法开数组来记录该串是否被记录.可能数据弱,结果hash竟然A了 .正确的解法是用set来存,把所有的hash值放进set,set有去重效果,最后求一下set的大小.但是这样结果是T了.不知道这题怎么解.一下是第一种代码.于是换别的,trie树来搞. Cr

poj 1200 Crazy Search

题目: 链接:点击打开链接 题意: 输入n和nc,以及字符串s,输出长度为n的不同字串的个数. 算法: 思路: 用hash判重(hash值......),看了大牛的代码,对hash还是不甚理解.... 代码: #include<iostream> #include<cstring> #include<cstdio> #include<cstdio> using namespace std; #define MAXN 16000010 const int MA

Poj 1200 Crazy Search(字符串Hash)

Poj 1200 题意:给你一个n和m以及一个有m个不同字母组成的字符串,问有多少个长度为n的不同字符子串: 题解:以m为进制进行Hash.虽然是看了解题报告才会的但必须要理解并且学会运用:https://www.cnblogs.com/gj-Acit/archive/2013/05/15/3080734.html. #include<cstring>//别用set,set的添加是红黑树实现时间复杂度是O(logN),在这里会超时 #include<cstdio> #define

【POJ 1200】Crazy Search(将字符映射为数字,将NC进制hash成10进制)

题目链接 题目链接 http://poj.org/problem?id=1200 题意 原字符串有NC个不同字母,统计原字符串长度为N的子字符串个数 解题思路 将字符按ASCII码映射成数字. 将n个字符,即n位NC进制拼起来. 将拼起来的n位NC进制转化为10进制. 将10进制映射入hash表,每次映射判断是否已经存在. 若不存在,则ans++:否则将hash设置为存在 如何将子串(n位NC进制)映射为10进制 a = 0 b = 1 c = 2 则 cbaa = 2 * 3^3 + 1 *

poj1200-Crazy Search(hash入门经典)

Hash:一般是一个整数.就是说通过某种算法,可以把一个字符串"压缩" 成一个整数.一,题意: 给出两个数n,nc,并给出一个由nc种字符组成的字符串.求这个字符串中长度为n的不同子串有多少种?二,思路: 1.这个题不用匹配,因为不高效. 2.将长度为n的子串看作n位的nc进制数,将问题转化为共有多少种十进制数字. 3.哈希时,每一个字符都对应这0 ~ nc-1的一个数字.三,步骤: 1.给nc个字母编号:0 ~ nc-1 hashArray[ch[i]] = k++; 2.明确每n个