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 16000005
using 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 1000000
using 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桶。