UVALive - 3942 - Remember the Word (Trie树)

UVALive - 3942

Remember the Word

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

Submit Status

Description

Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie.

Since Jiejie can‘t remember numbers clearly, he just uses sticks to help himself. Allowing for Jiejie‘s only 20071027 sticks, he can only record the remainders of the numbers divided by total amount of sticks.

The problem is as follows: a word needs to be divided into small pieces in such a way that each piece is from some given set of words. Given a word and the set of words, Jiejie should calculate the number of
ways the given word can be divided, using the words in the set.

Input

The input file contains multiple test cases. For each test case: the first line contains the given word whose length is no more than 300 000.

The second line contains an integer S , 1S4000 .

Each of the following S lines contains one word from the set. Each word will be at most 100 characters long. There will be no two identical words and all letters in the words
will be lowercase.

There is a blank line between consecutive test cases.

You should proceed to the end of file.

Output

For each test case, output the number, as described above, from the task description modulo 20071027.

Sample Input

abcd
4
a
b
cd
ab

Sample Output

Case 1: 2

Source

Regionals 2007 >> Asia
- Nanjing

Tire树,,前几次都是用结构体链表写得,,感觉用二维数组有点理不清,,这次看大白书用了二维数组描述的Trie树

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define LL long long
using namespace std; 

const LL maxnode    = 4010 * 100;
const LL sigma_size = 26;
const LL maxlen     = 100;
const LL maxn       = 300010;
const LL MOD        = 20071027;

char s[maxn];
int f[maxn];

struct Trie
{
	int ch[maxnode][sigma_size];
	int val[maxnode];
	int size; 		//结点总数
	Trie() {
		size = 1;
		memset(ch[0], 0, sizeof(ch[0]));
		memset(val,0,sizeof(val));
	} 		//初始时只有一个根结点
	void clear(){		//另一种初始化
         size = 1;
         memset(ch[0],0,sizeof(ch[0]));
         memset(val,0,sizeof(val));
    }

	int newnode(int u) {			//创建新结点
		memset(ch[size], 0, sizeof(ch[size]));
		val[size] = u;				//u为附加信息,这里为u=0,代表不是单词最后一个字母
		return size++;				//后一个结点
	}
	int idx(char c) { return c - 'a'; } 

	//插入字符串s,附加信息为v,v必须非0,因为0代表“本结点不是单词结点”
	void insert(char *s) {
		int u = 0, n = strlen(s);
		for(int i = 0; i < n; i++) {
			int c = idx(s[i]);
			if(!ch[u][c]) ch[u][c] = newnode(0);//结点不存在,创建新结点
			u = ch[u][c];						//往后走
		}
		val[u] = 1;//val[u] = v; 字符串的最后一个字符的附加信息为v,v为1表示这里是单词最后一个字母
	} 

	void find(int i, char *s) {
		int u = 0, len = 0;
		for(; *s; s++) {
			int c = idx(*s);
			if(ch[u][c]) {
				len++;
				u = ch[u][c];
                f[i+len] = (val[u] * f[i] + f[i + len]) % MOD;
                //递推法:f[i]表示从字符i开始的字符串(即后缀S[i..L])的分解方案数。
			}
			else break;
 		}
	}
};

Trie *trie;			//这里也可以这样(Trie trie;)下面注释括号里的内容为与此处同时修改的内容 

int main()
{
	int cas = 1;
	while(scanf("%s", &s) != EOF){
		int n, len = strlen(s);
		memset(f, 0, sizeof(f));
		f[0] = 1;
		trie = new Trie();			//初始时,要赋值给指针 ,( tire.clear(); ) 

		scanf("%d", &n);
		for(int i=0; i<n; i++){
			char tmp[110];
			scanf("%s", tmp);
			trie->insert(tmp);//调用插入函数,注意这里trie是指针 ( trie.insert(tmp); )
		}

		for(int i=1; i<=len; i++)
			trie->find(i-1, s+i-1);	//调用查找函数      ( trie.find(i-1, s+i-1);) 

		printf("Case %d: %d\n",	 cas++, f[len]);
	}
	return 0;
}
时间: 2024-12-23 04:50:03

UVALive - 3942 - Remember the Word (Trie树)的相关文章

UVALive 3942 Remember the Word 字典树+dp

/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5)和m个单词(每个单词长度最多100).单词都是不同的.该字符串可以由若干个单词组成,问最多有多少种组合方式. 思路:字典树+dp 用字典树处理好m个单词,定义dp[i]表示从i开始的字符串可以由单词组成的方式数. 那么dp[i] += dp[i+j]; j表示某个单词和字符串的[i,i+j-1]匹配

UVALive - 3942 Remember the Word[Trie DP]

UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem about words. Know- ing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remem

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie)

UVALive 3942 - Remember the Word(DP,数组Trie+指针Trie) ACM 题目地址: UVALive 3942 - Remember the Word 题意: 给一些单词,然后给一个长的单词,问有几种方法能组成这个大单词,单词可以重复用. 分析: DP[i]=sum{DP[j} (i<j<len),从后往前求. 本来用数组Trie写得爽爽的,1A了. 发现2s多,不能忍! 然后用指针Trie写了一遍,各种出错,整个人都不好了... 研究了一遍别人代码,发现快

UVALive - 3942 Remember the Word[树状数组]

UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device with a variable electric resistance. It has two terminals and some kind of control mechanism (often a dial, a wheel or a slide) with which the resistance

LA 3942 Remember the Word (Trie)

Remember the Word 题目:链接 题意:给出一个有S个不同单词组成的字典和一个长字符串.把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法? 思路:令d[i]表示从字符i开始的字符串(后缀s[i..L])的分解数,这d[i] = sum{d(i+len(x)) | 单词x是其前缀}.然后将所有单词建成一个Trie树,就可以将搜索单词的复杂度降低. 代码: #include<map> #include<set> #include<queue>

【暑假】[实用数据结构]UVAlive 3942 Remember the Word

UVAlive 3942 Remember the Word 题目: Remember the Word Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Neal is very curious about combinatorial problems, and now here comes a problem about words. Know

UVaLive 3942 Remember the Word (dp+字典树)

Remember the Word DescriptionNeal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remember nu

(trie)UVALive - 3942 Remember the Word

题目链接 设d[i]表示从下标i的字符开始的字符串的分解方法数,显然有倒序的递推公式. 需要求每个位置开始是否能组成模式串的前缀,才可以建立正确的递推. 1 #include <iostream> 2 #include <string> 3 #include <algorithm> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <qu

UVA 3942 -- Remember the Word (字典树+dp)

Remember the Word Neal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can't remember numbers clear