Crazy Search POJ - 1200

原题链接

考察: hash

错误思路:

       直接用字符串hash,但是字符串hash是针对给定长度求前缀的hash,这里明显不能使用

错误思路2:
        没有用变量给字符制造映射,而是直接用的ASCII码作映射,但是这样WA了,目前不知原因

正确思路:

        重新给字符制造映射,下标从1开始

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 typedef unsigned long long ull; 
 5 const int M = 0x3f3f3f;
 6 const int N = 1e7+10;//正常的哈希存储不同的种数 
 7 int h[N],ans,b[N];//此字符串长度不确定:而前缀哈希是预处理字符串的前缀哈希值的 
 8 int query(int x) 
 9 {//题目唯一给的数据范围不超过16000000是子串的字符个数,也就是说子串的长度是不确定的 
10     int k = (x%N+N)%N;
11     while(h[k]!=M&&h[k]!=x)
12     {
13         k++;
14         if(k==N) k=0;
15     }
16     return k;
17 }
18 int main()
19 {
20 //    freopen("in.txt","r",stdin);
21     int n,m;
22     scanf("%d%d",&n,&m);
23     string str; cin>>str;
24     int len = str.size();
25     for(int i =0,k=0;i<len;i++){
26         if(!b[str[i]]) b[str[i]] = ++k;
27         if(k==m) break;
28     }
29     fill(h,h+N,M);
30     for(int i=0;i<=len-n;i++){
31         int sum = 0;
32         for(int j=0;j<n;j++) sum = sum*m+b[str[i+j]];
33         int k = query(sum);
34         if(h[k]==M){
35             ans++; h[k] = sum;
36         }else continue;
37     }
38     printf("%d\n",ans);
39     return 0;
40 } 

 

posted @ 2021-01-06 22:27  acmloser  阅读(80)  评论(0编辑  收藏  举报