Trie数组相关应用:
1.每次先把号码一个一个存进str数组,每个数字位都++
2.判断如果一个号码每一位出现次数均大于1,说明其为前缀,输出”NO”
C++ 代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char str[N][15];
int son[N][10],cnt[N],f,idx;
void insert(char *s)
{
int p=0;
for(int i=0;s[i];i++)
{
int u=s[i]-'0';
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
cnt[p]++; //每一个位置都++,用于之后的判断
}
}
bool check(char *s)
{
int p=0;
for(int i=0;s[i];i++)
{
int u=s[i]-'0';
if(cnt[son[p][u]]==1) return false; //如果一个号码为1,那么这个号码之后的所有号码次数都为1,直接退出
p=son[p][u];
}
return true;
}
int main()
{
int n,m; cin>>n;
while(n--)
{
f=0;
idx=0;
memset(son[0],0,sizeof son);
memset(cnt,0,sizeof cnt);
cin>>m;
for(int i=0;i<m;i++)
{
scanf("%s",str[i]);
insert(str[i]);
}
for(int i=0;i<m;i++)
{
if(check(str[i])) //号码每个数字出现次数均大于1,说明此号码为其他更长的号码的前缀,所以不能构成电话列表
{
f=1;
break;
}
}
if(f==1) puts("NO");
else puts("YES");
}
return 0;
}
#include [HTML_REMOVED]
using namespace std;
const int N = 1e5 + 10;
int n, q, cnt[N], son[N][15];
string s[N];
int c;
void insert(string str)
{
int q = 0;
for(int i = 0; i < str.size(); i)
{
int u = str[i] - ‘0’;
if(son[q][u] == 0) son[q][u] = c;
q = son[q][u];
cnt[q]++;
}
}
bool check(string str)
{
int q = 0;
for(int i = 0; i < str.size(); i)
{
int u = str[i] - ‘0’;
if(cnt[son[q][u]] == 1) return 0;
q = son[q][u];
}
return 1;
}
int main()
{
int t;
cin >> t;
while(t–)
{
int c = 0;
int sum = 0;
memset(cnt, 0, sizeof(cnt));
memset(son, 0, sizeof(son));
bool flag = 0;
int n;
cin >> n;
for(int i = 1; i <= n; i) cin >> s[i], insert(s[i]);
for(int i = 1; i <= n; i++)
{
if(check(s[i]))
{
flag = 1;
break;
}
}
if(flag == 1) cout << “NO” << endl;
else cout << “YES” << endl;
}
为什么这么写就是Segmentation Fault 呢?求解,谢谢。
思路一级棒
思路很好,爱了
666