I - Article Decryption
Time Limit:1000ms Memory Limit:65536KB |
Description
|
You are given an dictionary in which there are N words.
Also, you are given an article with the length of L and
there`s no punctuation.
How many way can you translate this article?
|
Input
The first line is an integer T which stands for the number of test cases.
Then T test cases follow.
The first line of a test case contains an integer N (1<=N<=1000).
Each of the following N lines contains one word .
The length of each word is guaranteed to be less than or eaqul to 1000.
The next line contains some characters which describe the article.
The characters are lowercase letters.
|
Output
For each case output its answer after mod by 835672545.
|
Sample Input
2
5
ab
cb
bc
ba
a
abcba
3
a
ba
ab
ababa
|
Sample Output
2
3
|
題意:給定n個字符串和一篇文章,問用這些字符串組成這篇文章的方法有多少種。
分析:先將給定的字符串存入字典樹中,在樹中定義一個cnt用來記錄存入的每個字符串以最後一個字母結尾時的數量。這樣我們可以定義一個數組dp[MX]來記錄不同長度下的符合條件的組合方法。
dp[i] += dp[i-1] * query(s[ ])
query(s[ ])表示所查詢的字符串的個數
最終答案就是dp[len]
len爲文章的長度
代碼如下:
#include <map>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define mod 835672545
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int MX = 1e5 + 5;
int tot;
int dp[MX];
char temp[MX];
struct node{
int nxt[26];
int cnt;
void init(){
cnt = 0;
memset(nxt, 0, sizeof(nxt));
}
}tree[MX];
void add(char s[]){
int now = 0, x;
for(int i = 0; s[i] != '\0'; i++){
x = s[i] - 'a';
if(tree[now].nxt[x] == 0){
tree[++tot].init();
tree[now].nxt[x] = tot;
}
now = tree[now].nxt[x];
}
tree[now].cnt++;
}
int query(char s[]){
int now = 0, x;
for(int i = 0; s[i] != '\0'; i++){
x = s[i] - 'a';
if(tree[now].nxt[x]){
now = tree[now].nxt[x];
}
else return 0;
}
return tree[now].cnt;
}
int main() {
int t;
scanf("%d", &t);
while(t--){
tot = 0;
tree[0].init();
int n;
scanf("%d", &n);
char s[1005];
for(int i = 0; i < n; i++){
scanf("%s", s);
add(s);
}
scanf("%s", s+1);
memset(dp, 0, sizeof(dp));
memset(temp, 0, sizeof(temp));
int len = strlen(s+1);
dp[0] = 1;
for(int i = 1; i <= len; i++){
temp[i] = s[i];
for(int j = 1; j <= i; j++){
if(dp[j-1]){
dp[i] += dp[j-1] * query(temp + j);
}
if(dp[i] >= mod) dp[i] %= mod;
}
}
printf("%d\n", dp[len]);
}
return 0;
}