正题
给你一份情书
这题就是裸裸的字典树。
对于一个句子,我们把每一个单词提取出来,放进字典树内,如果有完全匹配的单词(存单词时标记一下最后一个节点),那么我们就加一,输出ans即可,注意要开一个bool数组来存储是否出现过单词。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int n;
int tot=0;
int son[5010][30];
int c[5010];
bool tf[5010];
struct Trie{
void Clear(){tot=1;memset(son[1],0,sizeof(son[1]));memset(c,0,sizeof(c,0,sizeof(c)));}
void Insert(char *s,int x){
int n=strlen(s);
int u=1;
for(int i=0;i<n;i++){
int now=s[i]-'a';
if(son[u][now]==0){
son[u][now]=++tot;
memset(son[tot],0,sizeof(son[tot]));
}
u=son[u][now];
}
c[u]=x;
}
int Find(char *s){
int n=strlen(s);
int u=1;
for(int i=0;i<n;i++){
int now=s[i]-'a';
if(son[u][now]!=0)
u=son[u][now];
else return 0;
}
return c[u];
}
}xx;
int main(){
scanf("%d",&n);
char s[1010];
xx.Clear();
for(int i=1;i<=n;i++){
scanf("%s",s);
int yu=strlen(s);
for(int j=0;j<yu;j++)
if(s[j]>='A' && s[j]<='Z') s[j]=s[j]-'A'+'a';
xx.Insert(s,i);
}
scanf("\n");
gets(s);
int n=strlen(s);
for(int i=0;i<n;i++)
if(s[i]>='A' && s[i]<='Z') s[i]=s[i]-'A'+'a';
char op[1010];
int tt=0;
tf[0]=true;
int ans=0;
for(int i=0;i<n;i++){
if(s[i]>='a' && s[i]<='z') op[tt++]=s[i];
else {
op[tt]='\0';
int p=xx.Find(op);
if(!tf[p]){
tf[p]=true;
ans++;
}
if(s[i]=='.'){
for(int i=1;i<=n;i++)
tf[i]=false;
tf[0]=true;
}
tt=0;
}
}
printf("%d\n",ans);
}