Trie树
程序员文章站
2022-05-19 18:54:59
...
暂时没学懂,先把板子放这吧。
题意:给出一个字符串和S个单词组成的字典,问把这个字符串分解成若干单词的连接,总共有多少种?(单词可重复)
思路:令d[i]表示从字符i开始的字符串的分解方案数,则dans[i]=sum{dans[i+d[x]] | 单词x是S[i…len]的前缀};
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
typedef long long LL;
const int maxn=300010;
const int MOD=20071027;
int d[maxn],len;
vector<int> ans;
struct node
{
node *next[30];
int value;
int num;
node()
{
for(int i=0;i<30;i++)
next[i]=NULL;
value=0;
}
}root;
string a;
int n;
void insert(string s)
{
node *p=&root;
int k=0,l=s.size();
while(k<l)
{
if(!p->next[s[k]-'a'])
p->next[s[k]-'a']=new node;
p=p->next[s[k]-'a'];
k++;
}
p->value=l;
}
void find(int x)
{
ans.clear();
node *p=&root;
int y=x;
while(x<len&&p->next[a[x]-'a']!=NULL)
{
if(p->next[a[x]-'a']->value)
ans.push_back(p->next[a[x]-'a']->value);
p=p->next[a[x]-'a'];
x++;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t=1;
string x;
while(cin>>a)
{
cin>>n;
len=a.size();
for(int i=0;i<30;i++)
root.next[i]=NULL;
for(int i=0;i<n;i++)
{
cin>>x;
insert(x);
}
memset(d,0,sizeof(d));
d[len]=1;
for(int i=len-1;i>=0;i--)
{
find(i);
for(int j=0;j<ans.size();j++)
d[i]=(d[i]+d[i+ans[j]])%MOD;
}
cout<<"Case "<<t++<<": ";
cout<<d[0]<<endl;
}
return 0;
}
或者直接在find的时候更新d数组
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=300010;
const int MOD=20071027;
int d[maxn],len;
struct node
{
node *next[30];
int value;
int num;
node()
{
for(int i=0;i<30;i++)
next[i]=NULL;
value=0;
}
}root;
string a;
int n;
void insert(string s)
{
node *p=&root;
int k=0,l=s.size();
while(k<l)
{
if(!p->next[s[k]-'a'])
p->next[s[k]-'a']=new node;
p=p->next[s[k]-'a'];
k++;
}
p->value=1;
p->num++;
}
void find(int x)
{
node *p=&root;
int y=x;//cout<<(p->next[a[x]-'a']==NULL)<<endl;
while(x<len&&p->next[a[x]-'a']!=NULL)
{
if(p->next[a[x]-'a']->value)d[y]=(d[y]+d[x+1])%MOD;
p=p->next[a[x]-'a'];
x++;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int t=1;
string x;
while(cin>>a)
{
cin>>n;
len=a.size();
for(int i=0;i<30;i++)
root.next[i]=NULL;
for(int i=0;i<n;i++)
{
cin>>x;
insert(x);
}
memset(d,0,sizeof(d));
d[len]=1;
for(int i=len-1;i>=0;i--)
find(i);
cout<<"Case "<<t++<<": ";
cout<<d[0]%20071027<<endl;
}
return 0;
作者:u010660276
来源:CSDN
原文:https://blog.csdn.net/u010660276/article/details/19678289
版权声明:本文为博主原创文章,转载请附上博文链接!
上一篇: 常见数据结构与算法题