标签:
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1381
此题可以用哈希数组求解,至于什么是哈希,可以先看以下这篇推荐文章,写得挺不错的。
推荐:http://www.cnblogs.com/yangecnu/p/Introduce-Hashtable.html#undefined
首先是求key值,我采取了,求余法。
key = value mod p
接着是确定value与p的值。
p的值根据可能的组合数进行确定。
而value的值,为采取了如下方法,假设子串长度为N,那么
int value = 0;
int tmp = 1;
for( int i=0; i<N; i++ ) {
value = ( c[i]-‘a‘+1 ) * tmp;
tmp = tmp << 1; // 等同于 tmp = tmp * 2
}
也就是根据每个字符在子串出现的位置,乘以2的相应次方
我采用了“拉链法”(在推荐的资料中有介绍)避免冲突。
因为我用了new申请内存,所以有一些delete操作;不过不用delete也是可以ac的。
建议初始声明的数组不要过大,否则很容易超内存
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;
typedef struct Node{
char *part;
Node *next;
}Node;
const int MUL_VALUE = 2;
const int LETTER_VALUE = 26 - 1; //设‘a‘为1, ‘z‘为26
const int MAXN = 3000000;
Node hash[MAXN];
int prime[6] = {23, 673, 17573, 456959, 2999999}; // 素数
int arrayLimit;
string s;
int N, NC;
void SetArrayLimit( int &NC );
int GetKey( int value );
void InsertValue( int value, char *part );
int Query( Node* target );
int main() {
int T;
int i, j;
int length;
int value, tmp;
char *part;
while( cin >> T ) {
while( T-- ) {
scanf( "%d%d", &N, &NC );
SetArrayLimit( NC );
cin >> s;
length = s.length();
value = 0;
tmp = 1;
part = new char[N];
for( i=0; i<N && i<length; i++ ) {
value = value + (s[i]-LETTER_VALUE )*tmp;
tmp = tmp << 1;
part[i] = s[i];
}
InsertValue( value, part );
for( i=N; i<length; i++ ) {
value = 0;
tmp = 1;
for( j=0; j<N; j++ ) {
value = value + ( s[ i-N+1+j ] - LETTER_VALUE )*tmp;
tmp = tmp << 1;
part[j] = s[ i-N+1+j ];
}
InsertValue( value, part );
}
int total = 0;
for( i=0; i<arrayLimit; i++ ) {
total += Query( hash[i].next );
hash[i].next = NULL;
}
cout << total << endl;
delete part;
}
}
return 0;
}
void SetArrayLimit( int &NC ) { // 确立此次使用的数组上限
int i=0;
int tmp = 26;
for( i=1; i<NC && tmp<=MAXN; i++ ) {
tmp *= 26;
}
for( i=0; i<4; i++ ) {
if( prime[i] >= tmp ) {
break;
}
}
arrayLimit = prime[i];
return ;
}
int GetKey( int value ) { // 得到key值
return value % arrayLimit;
}
void InsertValue( int value, char *part ) { // 插入值
int key = GetKey( value );
Node *target = &hash[key];
while( target->next!=NULL ) {
target = target->next;
if( strcmp( target->part, part )==0 ) {
return;
}
}
Node *t = new Node;
t->part = new char[N];
strcpy( t->part, part );
t->next = NULL;
target -> next = t;
return ;
}
int Query( Node* target ) { // 递归求出结果,同时方便delete操作
if( target == NULL ) {
return 0;
}
else {
int t = 1+Query( target->next );
delete target -> part;
delete target;
return t;
}
}
标签:
原文地址:http://www.cnblogs.com/Emerald/p/4280714.html