您的位置:首页 > 其它

POJ 3630 Phone List

2017-08-03 09:35 274 查看

题目链接:

http://poj.org/problem?id=3630

题意:

给你一串长度小于等于10的电话号码,问你,其中的一个是不是其他的前缀,如果是的话,就输出NO,全部不满足就YES。

题解:

典型的字典树的题目,但是直接动态建树,会超时,这里我们需要采用静态建树。

什么是动态建树,什么是静态建树,这里安利一个大佬的链接:

http://www.cnblogs.com/George1994/p/6346790.html

代码1(字典树静态建树)

#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f;
const int maxn = 1e5+10;
struct Tire
{
int cnt;
struct Tire *next[10];
Tire()
{
cnt=0;
for(int i=0;i<10;i++)
next[i]=NULL;
}
}tree[maxn];
string s[maxn];
int total;

void insert(Tire *&root,string s)
{
int len=s.size();
Tire *p=root;
for(int i=0;i<len;i++)
{
int pos=s[i]-'0';
if(!p->next[pos])
{
p->next[pos]=&tree[total];
total++;
}
p=p->next[pos];
p->cnt++;
}
return;
}

int search(Tire *&root,string s)
{
int len=s.size();
Tire *p=root;
if(root==NULL)
return 0;
for(int i=0;i<len;i++)
{
int pos=s[i]-'0';
p=p->next[pos];
if(p->cnt==1)
return 1;
}
return 0;
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
met(tree,0);
Tire *root=&tree[0];
total=1;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
cin>>s[i];
insert(root,s[i]);
}
int flag=0;
for(int i=0;i<n;i++)
{
if(!search(root,s[i]))
{
flag=1;
break;
}
}
if(flag)
printf("NO\n");
else
printf("YES\n");
}
}


代码2(STL):

#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define met(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f;
const int maxn = 1e4+10;
vector<string> p;

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
p.clear();
for(int i=0;i<n;i++)
{
string s;
cin>>s;
p.push_back(s);
}
sort(p.begin(),p.end());
bool flag=true;
for(int i=0;i<p.size()-1;i++)
{
if(p[i+1].find(p[i])==0)
{
flag=false;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj