LA 3942 背单词
2024-08-26 07:05:50
https://vjudge.net/problem/UVALive-3942
题意:
给出一个由S个不同单词组成的字典和一个长字符串。把这个字符串分解成若干个单词的连接,有多少种方法?比如,有4个单词a、b、cd、ab,则abcd有两种分解方法:a+b+cd和ab+cd。
思路:
建立字典树,查询的时候令d(i)表示从字符i开始的字符串的分解方案数,则d(i)=sum{d(i+len(x))|单词x是S[i..L]的前缀}。
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std; const int maxnode = * + ;
const int sigma_size = ;
const int maxn = + ;
char str[maxn],s[+];
int n, dp[maxn]; struct Trie
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz; void init()
{
sz = ;
memset(ch[], , sizeof(ch[]));
} void insert(char *s, int v)
{
int u = , len = strlen(s);
for (int i = ; i < len; i++)
{
int c = s[i] - 'a';
if (!ch[u][c])
{
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = v;
} int find(char *s, int pos)
{
int len = strlen(s), u = , ans = ;
for (int i = pos; i < len; i++)
{
int c = s[i] - 'a';
if (ch[u][c] == ) break;
u = ch[u][c];
if (val[u] == )
ans = (ans + dp[i + ]) % ;
}
return ans;
}
}T; int main()
{
//freopen("D:\\txt.txt", "r", stdin);
int kase = ;
while (~scanf("%s", str))
{
scanf("%d", &n);
T.init();
for (int i = ; i < n; i++)
{
scanf("%s", s);
T.insert(s, );
}
int len = strlen(str);
dp[len] = ;
for (int i = len - ; i >= ; i--)
dp[i] = T.find(str, i);
printf("Case %d: %d\n", ++kase, dp[]);
}
return ;
}
最新文章
- EF常用查询写法
- paas架构之docker——安装
- 去除冗余 – 精简您的CSS样式代码
- HeadFirst jsp 02 (体系结构)
- 安装Win7和Ubuntu12.04双系统后,意外删除Ubuntu12.04引导文件,出现error:unknown filesystem;grub rescue>;错误的解决方案
- Oberon程序设计语言简介
- MySQL的my-innodb-heavy-4G.ini配置文件的翻译
- 【ASP.NET Core】运行原理之启动WebHost
- JS画图之七【时钟】
- python提取网页表格并保存为csv
- listview的gridview视图中,获取列中模板内的button按钮(找控件内的控件)
- SpringMvc执行过程
- linux软链接和硬链接的区别
- ajax批量删除功能的实现源代码
- Nginx作为TCP负载均衡
- Python利用Plotly实现对MySQL中的数据可视化
- win server 2008 R2 安装IIS
- 关于Android开发环境的演变
- spark join
- 解题:洛谷4178 Tree