POJ3630 Phone List
题意
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let's say the phone catalogue listed these numbers:
- Emergency 911
- Alice 97625999
- Bob 91125426
In this case, it's not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob's phone number. So this list would not be consistent.
给若干数字串,问有没有两个串满足一个串是另一个串的前缀.
分析
参照jklover的题解。
将读入的串一个个插入 Trie 树中,不难发现串 A 是串 B 的前缀,只有两种情况.
- 一种情况是串 A 先被插入,那么在插入串 B 时,一定会经过 A 的单词节点.
- 另一种情况是串 B 先被插入,那么在插入串 A 时,都是沿着 B 的边走的,并没有新建边.一边插入,一边判断这两种情况是否出现即可.
另一个简单而有效的做法是hash.将出现过的前缀全部用 vis 数组标记即可.
时间复杂度:线性。
代码
细节挺多。
//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read()
{
rg T data=0,w=1;
rg char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') w=-1;
ch=getchar();
}
while(isdigit(ch))
{
data=data*10+ch-'0';
ch=getchar();
}
return data*w;
}
template<class T>il T read(rg T&x)
{
return x=read<T>();
}
typedef long long ll;
co int N=1e5+1;
namespace T
{
int tot;
int ch[N][10],val[N];
void init()
{
tot=0;
std::fill(ch[0],ch[0]+10,0);; // edit 2
val[0]=0;
}
int newnode()
{
++tot;
std::fill(ch[tot],ch[tot]+10,0);;
val[tot]=0;
return tot;
}
bool ins(char*s,int n)
{
int u=0,valid=0;
for(int i=0;i<n;++i)
{
int k=s[i]-'0';
if(!ch[u][k])
{
ch[u][k]=newnode();
valid=1; // edit 1
}
u=ch[u][k];
if(val[u])
return 0;
}
if(!valid)
return 0;
val[u]=1;
return 1;
}
}
char buf[20];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int kase=read<int>();
while(kase--)
{
T::init();
int n=read<int>(),valid=1;
while(n--)
{
scanf("%s",buf);
if(!valid) continue;
if(!T::ins(buf,strlen(buf))) valid=0;
}
puts(valid?"YES":"NO");
}
return 0;
}
静渊以有谋,疏通而知事。