Uva1401
初步的转移想法是一种 n2 的
就是 O(n) 枚举位置再 O(n) 枚举断点转移的那种
发现单词的长度不超过 100,就可以暴力了
每个位置匹配一下就可以了
由于不会有重复单词,用 Trie 树来‘加速’匹配
代码:
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cctype>
#include <cstdio>
#include <locale>
using namespace std;
const int MAXL = 300005, MAXS = 4005, mod = 20071027;
struct Node {
int nxt[26];
bool isend;
}t[MAXS * 105];
char txt[MAXL], wrd[105];
int s, ptr, len, tot;
int f[MAXL];
inline int newnode() {
++ptr;
memset(t + ptr, 0, sizeof(Node));
return ptr;
}
inline void Insert(char *s) {
register int LEN = strlen(s), cur = 0;
for (int i = 0; i < LEN; ++i) {
register int x = s[i] - 'a';
if (!t[cur].nxt[x]) t[cur].nxt[x] = newnode();
cur = t[cur].nxt[x];
}
t[cur].isend = true;
}
inline void work(int pos) {
register int cur = 0;
for (int i = pos; i < len; ++i) {
register int x = txt[i] - 'a';
if (!t[cur].nxt[x]) return;
cur = t[cur].nxt[x];
if (t[cur].isend) f[pos] = (f[pos] + f[i + 1]) % mod;
}
}
inline void clearall() {
memset(f, 0, sizeof(f));
memset(t + 0, 0, sizeof(Node));
ptr = 0;
return;
}
int main() {
while (~scanf("%s", txt)) {
clearall();
scanf("%d", &s);
for (int i = 1; i <= s; ++i) {
scanf("%s", wrd);
Insert(wrd);
}
len = strlen(txt);
f[len] = 1;
for (int i = len - 1; i >= 0; --i)
work(i);
printf("Case %d: %d\n", ++tot, f[0]);
}
return 0;
}
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/

浙公网安备 33010602011771号