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 ull unsigned long long
using namespace std;
const int N=1e7+6e6+5;
using namespace std;
int p[N];
int len;
char str[N];
bool hash_[N];
int main(){
    int n,m;
    scanf("%d %d %s",&n,&m,str+1);
    len=strlen(str+1);
    int j=0;
    for(int i=1;i<=len;i++){
        if(!p[str[i]])p[str[i]]=++j;//以m为进制数,将各个字母分别用数字表示进行hash
        if(j==m)break;
    }
    ull Base=1;
    ull Hash=0;
    for(int i=1;i<=n;i++){//首先将前n个数将m进制转换为10进制
        Hash=Hash*m+p[str[i]]-1;//减一是为了因为m进制数为0到m-1
        Base*=m;
    }
    Base/=m;
    hash_[Hash]=1;
    int ans=1;
    for(int i=2;i+n<=len+1;i++){
        Hash=(Hash-(p[str[i-1]]-1)*Base)*m+p[str[i+n-1]]-1;//原Hash减去子串首字母代表的数乘以Base得到的是剩下字母所生成的10进制数那么再乘以一个m在加上新进的一个字母所代表的数,得到的是新子串所代表的10进制数(即其hash值)
        if(!hash_[Hash]){
            hash_[Hash]=1;
            ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Mrleon/p/8424434.html

时间: 2024-08-01 05:40:44

Poj 1200 Crazy Search(字符串Hash)的相关文章

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

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 --- 不错的字符串HASH构造方法

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

【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 *

POJ 1200 字符串HASH

题目链接:http://poj.org/problem?id=1200 题意:给定一个字符串,字符串只有NC个不同的字符,问这个字符串所有长度为N的子串有多少个不相同. 思路:字符串HASH,因为只有NC个不同的字符,所以我们可以把字符串看成是一个NC进制的串,然后计算出字符串的前缀HASH.然后枚举起点判断子串的HASH值是否已经存在.因为有了前缀HASH值,所以转移是O(1)的. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #in

[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

poj 1200 (hash)

Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23168   Accepted: 6513 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

字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在学习后缀数组的时候已经做过一遍了,但是现在主攻字符串hash,再用字符串hash写一遍. 这题的思路是这样的: 1)取较短的串的长度作为high,然后二分答案(每次判断长度为mid=(low+high)>>1是否存在,如果存在就增加下界:不存在就缩小上界): 2)主要是对答案的判断(judge函数