【字典树】
数组模板
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define idx(x) x - 'a';
const int MAXN = 1e6;
struct Trie
{
int next[26];
int val;
}tree[MAXN];
int nxt, T;
char str[MAXN];
int add()
{
memset(&tree[nxt], 0, sizeof(Trie));
return nxt++;
}
void Insert(char *s)
{
int rt = 0, len = strlen(s);
for(int i = 0; i < len; i++)
{
int c = idx(s[i]);
if(!tree[rt].next[c])
{
tree[rt].next[c] = add();
}
rt = tree[rt].next[c];
}
tree[rt].val++;
}
bool Find(char *s)
{
int rt = 0, len = strlen(s);
for(int i = 0; i < len; i++)
{
int c = idx(s[i]);
if(!tree[rt].next[c]) return false;
rt = tree[rt].next[c];
}
if(tree[rt].val) return true;
return false;
}
int main()
{
memset(&tree[0], 0, sizeof(Trie));
nxt = 1;
scanf("%d", &T);
while(T--)
{
scanf("%s", str);
Insert(str);
}
while(~scanf("%s", str))
{
if(Find(str)) puts("exist");
else puts("none");
}
return 0;
}
POJ 2001 Shortest Prefixes(求字符串非公共的最短前缀,记录每个节点上的单词数)
HDU 1671 Phone List (也就是 POJ 3630 Phone List)
如果有前缀存在,一共就两种可能性
1、短的出现在长的前面
2、短的出现在长的后面
这一题其实也可以不用字典树的
字典树版
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
char s[100005][15],str[25];
int nxt,flag;
struct Trie
{
int next[26];
int val;
}tree[100005];
int add()
{
memset(tree[nxt].next, 0, sizeof(tree[nxt].next));
tree[nxt].val=0;
return nxt++;
}
void insert(char *st)
{
int rt=0,len=strlen(st);
int ff=0;
for(int i=0;i<len;i++)
{
int c=st[i]-'0';
if(!tree[rt].next[c])
{
tree[rt].next[c]=add();
if(tree[rt].val>0) flag=0;
ff=1;
}
rt=tree[rt].next[c];
}
tree[rt].val++;
if(ff==0) flag=0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
nxt=1;
int n;
scanf("%d",&n);
flag=1;
memset(s,'\0',sizeof(s));
memset(tree,0,sizeof(tree));//一定要注意,没有清零wa了好久,所以贴个代码纪念一下
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
insert(s[i]);
}
if(flag==0) printf("NO\n");
if(flag==1) printf("YES\n");
}
return 0;
}
非字典树版
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int main()
{
string str[10010];
int t,n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>str[i];
}
sort(str,str+n);//排序之后,如果存在前缀关系,那么排序后,长的必定出现在短的后一个
int flag=0;
for(int i=0;i<n;i++)
{
int len=str[i].length();
string tmp=str[i+1].substr(0,len);
if(tmp==str[i])
{
flag=1;
break;
}
}
if(flag==1) printf("NO\n");
if(flag==0) printf("YES\n");
}
return 0;
}
这个用了c++的一些知识点
string在c++中的用法http://jingyan.baidu.com/article/20b68a8854f919796dec6265.html
HDU 1247 Hat’s Words
可以试试用string+map的方法
【KMP】
【ac自动机】