【USACO2.3.1】最长前缀 KMP(爆内存) 暴力(居然更快还AC)
来源:互联网 发布:linux tomcat安装版 编辑:程序博客网 时间:2024/05/22 14:34
真的很奇怪,在其他OJ上交了,速度很快排到第二(最慢一个点80ms)。。但是用内存挺多的。
交USACO的时候,在用了15.8M内存的时候RE了。 我猜是限了16M内存。 看来不能省事……我得去重写了
/*TASK:prefixLANG:C++*/#include <cstdio>#include <cstring>#include <queue>#include <iostream>using namespace std;char s[220][220], text[200115];int next[220000];int stail = 0;struct edge{int v;edge *next;edge(){v = - 1;next = NULL;}edge(int x, edge *p){v = x;next = p;}}*a[200005]={NULL};//vvoid init(){while (1){scanf("%s", s[stail++]);if (s[stail - 1][0] == '.'){-- stail;break;}}int textlen = 0;char ch;while ((ch = getchar()) != EOF){if (ch == '\n')continue;text[textlen++] = ch;}text[textlen] ='\0';for (int i = 0; i != 200005; ++ i)a[i] =NULL;}inline void ins(int x, int y) // x可以到y{a[x] = new edge(y, a[x]);}inline void kmp(char *son, char *text, int son_length, int text_length){int i = 0, j = -1;next[0] = -1;while (i != son_length){if (j == -1 || son[i] == son[j])next[++i] = ++j;else j = next[j];}i = 0, j = 0;while (i != text_length){if (j == -1 || text[i] == son[j])++i, ++j;else j = next[j];if (j == son_length) //j已经超出范围了{ins(i - son_length, i);j = next[j];}}}queue<int>q;bool vis[200005]={0};void doit(){for (int i = 0; i != stail; ++ i)kmp(s[i], text, strlen(s[i]), strlen(text));q.push(0);vis[0] = true;while (!q.empty()){int now = q.front();q.pop();for (edge *i = a[now]; i != NULL; i = i -> next){int will = i -> v;if (!vis[will]){vis[will] = true;q.push(will);}}}int tmp = strlen(text);for (int i = tmp; i >= 0; -- i)if (vis[i]){printf("%d\n", i); return;}}int main(){freopen("prefix.in","r",stdin);freopen("prefix.out","w",stdout);init();doit();return 0;}
写了一个暴力的…… 然后尼玛这么快? 在BSOJ上居然是第一……(上面的KMP是第三)
Executing... Test 1: TEST OK [0.008 secs, 3896 KB] Test 2: TEST OK [0.008 secs, 3896 KB] Test 3: TEST OK [0.005 secs, 3896 KB] Test 4: TEST OK [0.008 secs, 3896 KB] Test 5: TEST OK [0.005 secs, 3896 KB] Test 6: TEST OK [0.041 secs, 3896 KB]
但是不爆内存了显然~而且速度快。显然是数据弱了……但是实际上如果极限数据,2个算法的时间复杂度应该差不多,毕竟串短……,但是显然后者更节约内存
方法: 从0位置开始,把每个串都匹配一下…… 如果从4位置开始,匹配了一个长度3的串,那么把7塞进队列。 因为5,6根本不用匹配了,因为没有串以他们为结尾……
/* TASK:prefixLANG:C++*/#include <cstdio>#include <cstring>#include <queue>char s[201][11], text[200005];int length[201];bool vis[200005]={1,0};int stail = 0, textlen=0;inline void init(){while (1){scanf("%s", s[stail++]);length[stail - 1] = strlen(s[stail - 1]);if (s[stail - 1][0] == '.'){-- stail;break;}}char ch;while ((ch = getchar()) != EOF){if (ch == '\n')continue;text[textlen++] = ch;}for (int i = 0; i != 15; ++ i)text[textlen++] = '#';text[textlen] ='\0';}std::queue<int>q;inline bool check(char *son, char *text, int son_length){for (int i = 0; i != son_length; ++ i)if (son[i] != text[i])return false;return true;}inline void doit(){int i, will, ans = 0;q.push(0);while (!q.empty()){ans = q.front();q.pop();for (i = 0; i != stail; ++ i){will = ans + length[i];if (vis[will])continue;if (check(s[i],text+ans, length[i])){vis[will] = 1;q.push(will);}}}printf("%d\n",ans);}int main(){freopen("prefix.in","r",stdin);freopen("prefix.out","w",stdout);init();doit();return 0;}
0 0
- 【USACO2.3.1】最长前缀 KMP(爆内存) 暴力(居然更快还AC)
- P1809【USACO2.3.1】Longest Prefix最长前缀 IOI'96
- [USACO2.3]最长前缀 Longest Prefix
- CSU 1598: 最长公共前缀(KMP)
- POJ 1961(KMP前缀最长重复子串)
- CSU 1598 最长公共前缀 【KMP】
- KMP(前缀数组)
- leetcode——Longest Common Prefix 最长公共前缀(AC)
- HDU 5073 Galaxy(居然是暴力)
- poj 3080(3450) KMP(暴力也能过) 多个串的最长公共子串
- CSU 1598 最长公共前缀 KMP连续匹配
- 最长公共前缀(LCP)
- usaco最长前缀(dp)
- HDU5510 - Bazinga (kmp+暴力)
- HDU 2087 (KMP||暴力)
- 最长前缀
- 最长前缀
- HDU 5273(暴力前缀和)
- 【Linux基础笔记】虚拟机下的centOS不能自动获取IP地址<二>
- 属性动画PropertyAnimation 小试牛刀
- 无法显示TabHost的setIndicator设置的图片的问题解决办法
- linux系统备份命令
- 套接字工厂——ServerSocketFactory
- 【USACO2.3.1】最长前缀 KMP(爆内存) 暴力(居然更快还AC)
- 【C/C++】int *p[4]与int (*q)[4]的区别
- java.ByteArrayInputStream与ByteArrayOutputStream浅谈
- BZOJ 1861 书架(splay)
- OC_类
- 【C/C++】C/C++ 中二维数组传递的三种方式
- 分红酒
- html常用标签及说明
- BufferedOutputStream和ByteArrayOutputStream区别