poj1200Crazy Search (hash)

来源:互联网 发布:淘宝图标图片素材 编辑:程序博客网 时间:2024/06/03 19:47

题目大意就是给你一个字符串,由NC种字母组成,要你求它有多少个长度为N的且不同的子串

题目是放在hash和并查集的专栏里,于是一开始拿到题便往并查集的方向去想,想了半天想不出来,一看题解,哈希?exm?

认认真真的看了大佬的思路,恍然大悟,牛逼,牛逼,居然能想到转化为进制来做,一举两得啊,一来hash函数都不用写,开个数组就好了,二来代码超好写,两个for循环就能搞定

代码

#include<iostream>#include<cstring>#include<cstdio>using namespace std;const int nmax=16000005;int vis[30];  //总共也才26个字母,30够了int hashh[nmax]; char s[nmax];int main(){    int N,M;    while(~scanf("%d%d%s",&N,&M,s))    {        memset(vis,0,sizeof vis);        memset(hashh,0,sizeof hashh);        int cnt=0;        vis[s[0]-'a']=cnt++;  这个字母对应M进制下的cnt        int n=strlen(s);        for(int i=1;i<n;i++)            if(!vis[s[i]-'a'])            vis[s[i]-'a']=cnt++;        int ans=0;        for(int i=0;i<=n-N;i++)        {            int sum=0;            for(int j=i;j<i+N;j++)                sum=sum*M+vis[s[j]-'a'];  求出M进制下的这个子串所对应的数值,一定是唯一的,不会有两个不同的串转化后的值相等            if(!hashh[sum])            {                ans++;                hashh[sum]++;            }        }        printf("%d\n",ans);    }    return 0;}


原创粉丝点击