Hdu 1381 Crazy Search
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1381
此题可以用哈希数组求解,至于什么是哈希,可以先看以下这篇推荐文章,写得挺不错的。
推荐:http://www.cnblogs.com/yangecnu/p/Introduce-Hashtable.html#undefined
首先是求key值,我采取了,求余法。
1 | key = value mod p |
接着是确定value与p的值。
p的值根据可能的组合数进行确定。
而value的值,为采取了如下方法,假设子串长度为N,那么
1 2 3 4 5 6 | 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的。
建议初始声明的数组不要过大,否则很容易超内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | #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; } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步