/* THE PROGRAM IS MADE BY PYY */ /*----------------------------------------------------------------------------// Copyright (c) 2011 panyanyany All rights reserved. URL : http://acm.hdu.edu.cn/showproblem.php?pid=2222 Name : 2222 Keywords Search Date : Tuesday, 18 August, 2011 Time Stage : Many hours ..... Result: 4445107 2011-08-18 19:53:24 Accepted 2222 234MS 30152K 3051 B C++ pyy Test Data: Review: 第二次做了,感觉比第一次更容易理解了。不过还是出了很多错误 //----------------------------------------------------------------------------*/ #include <stdio.h> #include <string.h> #include <stdlib.h> #define max(a, b) (((a) > (b)) ? (a) : (b)) #define min(a, b) (((a) < (b)) ? (a) : (b)) #define infinity 0x7f7f7f7f #define minus_inf 0x80808080 #define MAXSIZE 1000009 #define LESSMAX 55 typedef struct tagNODE { // int fail ; int cnt ; struct tagNODE * child[26], * fail ; } NODE ; char model[MAXSIZE], pattn[LESSMAX] ; int tcase, n ; int stkPtr ; // pointer for stack int head, tial ; // pointers for queue int count ; // match words count NODE * tmp, * newNode, * childNode, * parntNode ; NODE * stack[LESSMAX * 10000], * queue[LESSMAX * 10000] ; #define root stack[0] void makeTrie () { int i, j ; int len = strlen (pattn) ; tmp = stack[0] ; for (i = 0 ; i < len ; ++i) { j = pattn[i] - 'a' ; if (!tmp->child[j]) { newNode = (NODE *) calloc (1, sizeof (NODE)) ; stack[stkPtr++] = newNode ; // 注意1 tmp->child[j] = newNode ; } tmp = tmp->child[j] ; // printf ("%c: %d, cnt: %d\n", pattn[i], tmp, tmp->cnt) ; } ++tmp->cnt ; // printf ("-------.%c, %d\n", pattn[i-1], tmp->cnt) ; } void makeFail () { int i, j ; head = tial = 0 ; for (i = 0 ; i < 26 ; ++i) if (root->child[i]) { root->child[i]->fail = root ; queue[tial++] = root->child[i] ; } while (head < tial) { parntNode = queue[head++] ; for (i = 0 ; i < 26 ; ++i) { childNode = parntNode->child[i] ; if (childNode) { tmp = parntNode->fail ; while (tmp && !tmp->child[i]) tmp = tmp->fail ; if (tmp) childNode->fail = tmp->child[i] ; else childNode->fail = root ; queue[tial++] = childNode ; } } } } void ACAutomation () { int i, j ; int len = strlen (model) ; NODE * tmpFail ; tmp = root ; for (i = 0 ; i < len ; ++i) { j = model[i] - 'a' ; while (!tmp->child[j] && tmp != root) tmp = tmp->fail ; tmp = (tmp->child[j]) ? tmp->child[j] : tmp ; // 在相同递减后缀并且未被匹配过的字符串间跳跃 // 并且记录cnt 值,然后清空cnt 值,表示以此 // 字符结尾的这个单词已经记录过了 // 但要注意,用来跳跃的指针变量,由于要不断地 // 改变,即通过fail 指针向根寻找,所以要另外 // 使用一个临时变量,不能直接用tmp 否则在下 // 一次的for循环就会没用了 tmpFail = tmp ; while (tmpFail->cnt) { // printf ("%c\n", model[i]) ; count += tmpFail->cnt ; tmpFail->cnt = 0 ; tmpFail = tmpFail->fail ; } } } void recycle () { while (stkPtr) free (stack[--stkPtr]) ; } int main () { int i, j ; while (scanf ("%d", &tcase) != EOF) { while (tcase--) { count = 0 ; stkPtr = 1 ; // 如果用了0 ,在“注意1” // 里stack[0]的值会被覆盖掉,然后不断悲剧…… stack[0] = (NODE *) calloc (1, sizeof (NODE)) ; scanf ("%d", &n) ; for (i = 0 ; i < n ; ++i) { scanf ("%s", pattn) ; getchar () ; makeTrie () ; } scanf ("%s", model) ; // 这一步经常忘 makeFail () ; ACAutomation () ; printf ("%d\n", count) ; recycle () ; // 释放内存 } } return 0 ; }
------------------------------------新旧世纪永恒的分割线---------------------------------------------------
纠结啊~郁闷啊~这题是所谓的 ac自动机 模版题 居然一直爆内存?!!试了我几天几十次啊!!纠结啊。悲剧啊。我对比了下人家的代码,感觉自己的数组明明开得比人家少啊!怎么还是爆了?一开始以为是用了 queue类 的问题,但后来改用静态数组,依旧爆!今天,没有办法了,全部改用 calloc 并且及时释放内存,不开结构体数组了,只开了两个结构体指针数组。好吧,辛辛苦苦,终于提交了……AC了,内牛满面啊~~~老天啊,您老人家终于肯看我一眼了么?
附上大牛的解题报告:
http://www.cppblog.com/mythit/archive/2009/07/30/80633.html
http://www.cnblogs.com/destinydesigner/archive/2009/10/15/1584191.html
http://www.dev-club.net/xiangxixinxi/22010072906013413/201102100439240.html
4075629 |
2011-06-18 14:40:59 |
Accepted |
203MS |
30184K |
C++ |
|||
4069611 |
2011-06-14 20:10:26 |
Memory Limit Exceeded |
62MS |
55052K |
C++ |
|||
4069609 |
2011-06-14 20:09:48 |
Memory Limit Exceeded |
31MS |
33368K |
G++ |
|||
4069607 |
2011-06-14 20:09:32 |
Memory Limit Exceeded |
62MS |
55124K |
G++ |
|||
4069605 |
2011-06-14 20:06:38 |
Memory Limit Exceeded |
62MS |
55052K |
C++ |
|||
4069604 |
2011-06-14 20:05:47 |
0MS |
0K |
C++ |
||||
4069602 |
2011-06-14 20:05:15 |
Memory Limit Exceeded |
62MS |
55056K |
C++ |
|||
4069451 |
2011-06-14 18:19:49 |
Runtime Error |
62MS |
6728K |
C++ |
|||
4069377 |
2011-06-14 17:27:08 |
Wrong Answer |
312MS |
28464K |
C++ |
|||
4069374 |
2011-06-14 17:25:54 |
Memory Limit Exceeded |
62MS |
55064K |
C++ |
|||
4069373 |
2011-06-14 17:25:42 |
Memory Limit Exceeded |
62MS |
55064K |
C++ |
|||
4069368 |
2011-06-14 17:23:55 |
Memory Limit Exceeded |
46MS |
55056K |
G++ |
|||
4069365 |
2011-06-14 17:21:47 |
Memory Limit Exceeded |
62MS |
55056K |
G++ |
|||
4069364 |
2011-06-14 17:21:36 |
Memory Limit Exceeded |
62MS |
55068K |
C++ |
|||
4069363 |
2011-06-14 17:20:12 |
Memory Limit Exceeded |
62MS |
55068K |
C++ |