poj 字符串相关之1200 Crazy Search

来源:互联网 发布:java web经典面试题 编辑:程序博客网 时间:2024/06/14 03:53

poj 字符串相关之1200 Crazy Search

题目链接http://poj.org/problem?id=1200
最开始看了题目,觉得简单,就用了map,结果时间超了

#include<cstdio>#include<string>#include<iostream>#include<algorithm>#include<memory.h>#include<map>#define INF 16000005using namespace std;char a[INF];map<string , int> mp;int main(){    int N, NC, i, j, t, ans, len;    scanf("%d%d", &N, &NC);    scanf("%s", a);    len = strlen(a);    t = len - N ;    ans = 0;    for (i = 0; i <= t; i++)    {        string s(a + i, N);        if (!mp[s])        {            ans++;            mp[s] = 1;        }    }    printf("%d\n", ans);}

于是学习了hash,代码如下:

#include<cstdio>#include<string>#include<iostream>#include<algorithm>#include<memory.h>#include<map>#define INF 16000005#define MAXNUM 1000000using namespace std;char a[MAXNUM], c[160];bool Hash[INF];map<string , int> mp;int main(){    int N, NC, i, j, t, sum, ans, len;    memset(Hash, 0, sizeof(Hash));    scanf("%d%d", &N, &NC);    scanf("%s", a);    len = strlen(a);    t = len - N ;    ans = 0;    for (i = 0, j = 0;; i++)    {        if (!c[a[i]])        {            c[a[i]] = ++j;        }        if (j == NC)            break;              }    for (i = 0; i <= t; i++)    {        sum = 0;        for (j = i; j < i + N; j++)        {            sum = sum*NC + c[a[j]];        }        if (!Hash[sum])        {            ans++;            Hash[sum] = 1;        }    }    printf("%d\n", ans);}

最后运行:16488K 79MS
第一次用Hash,所以解释一下原因。将字符串看成NC进制的数,每一个字符代表不同的数字,譬如在这里a代表97,可能97位置处的数字可能代表j(1<=j<=NC)。假设是子字符串aa,则它代表的数字是(jj)NC进制。然后每一个子字符串映射到hash桶中,问题就转化为了求一共有多少个hash桶。