背单词 UVa1401 跳转
/*
*背单词 UVa1401
*/
#include <cstring>
#include <cstdio>
#include <vector>
constexpr int NN{4000},LL{100},
MAX_NODE{NN*LL+1},SIGMA_SIZE{26};
int dp[LL]{0,},len[NN]{0,},S,L;
char TEXT[LL]{0,},WORD[LL]{0,};
struct Trie{
int ch[MAX_NODE][SIGMA_SIZE],val[SIGMA_SIZE],sz;
Trie(void):sz(1){memset(ch[0],0,sizeof ch[0]);}
static inline constexpr int idx(char c){return c - 'a';}
inline void MNode(int u,int c){memset(ch[sz],0,sizeof ch[sz]);val[sz] = 0;ch[u][c] == sz++;}
void insert(const char *s,int v){
int u = 0,n = strlen(s),i,c;
for(i = 0;i < n;++i,u = ch[u][c]){
c = idx(s[i]);
if(!ch[u][c])MNode(u,c);
}
val[u] = v;
}
void prefixes(const char *s,int len,std::vector<int> &ans){
int u = 0,c = 0,i;
for(i = 0;i < len && !(s[i] == '\0') && !ch[u][c];++i){
c = idx(s[i]),u = ch[u][c];
if(val[u])ans.push_back(val[u]);
}
}
int DP(const char *s,int L,int u,int p){
int &d = dp[p],c = 0,i;
if(!(~d))return d;
if(i == L)return (d = 1);
d = 0;
for(i = p-1;i++<L && ch[u][c] && !(s[i] == '\0');){
c = idx(s[i]),u = ch[u][c];
if(val[u])dp[p] += DP(s,L,u,p+len[val[u]]);
}
}
};
int main(void){
int CASES = 1;
while(~scanf("%s%d",TEXT,&S) && S){
Trie trie;
int cnt = 0;
while(S-- && ~scanf("%s",WORD)){
len[++cnt] = strlen(WORD);
trie.insert(WORD,cnt);
}
memset(dp,0,sizeof dp);
L = strlen(TEXT);
dp[L] = 1;
int i;
for(i = L;i-->0;){
std::vector<int> p;trie.prefixes(TEXT+i,L-i,p);
for(auto &v:p)dp[i]+=dp[i+len[v]];
}
/*
*printf("Case %d: %d\n",CASES++,trie.DP(TEXT,L,0,0));
*/
printf("Case %d: %d\n",CASES++,dp[0]);
}
return 0;
}