题目链接:点击打开链接
题目大意:如果一个电话号码为另一个电话号码的前缀,那么就打不通,判为NO
题目分析: trie 树的资料见我的转载 点击打开链接
先将电话号码排序,从长到短,进行处理,详见代码,注意数组的大小
题目心得:完全自己第一次写的Trie 树,一开始先学习trie 白书2 P 209,然后 做这道题,写完后wa了2 次,觉得自己写的没有错啊奇葩的数据都过了,单色还是wa
今天早上不甘心,再次看才发现申请的Trie tmp 是一用到底的,正确的是应该每一组数据申请新的tmp,因为要付初值……
其实好几次都是这样,代码自己觉得姿势很优美啊,没问题啊,结果都是小问题,要么是初值,要么是cmp函数写错了,要么是函数返回值将long long 改为了int ,要 么是while(t--)while(~)sigh!加油吧,一边前行,一边总结
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 100010
struct Trie
{
int chart[maxn][11];
int a;
Trie (){a=1;memset(chart[0],0,sizeof(chart[0]));}
int idx(char c) { return c-'0';}
bool insert(char *s)
{
int u=0,n = strlen(s),flag=1;
for(int i=0; i<n ;i++)
{
int c=idx(s[i]);
if(!chart[u][c])
{
flag=0; //用于标记短的号码是否有不同于长的号码处,
memset(chart[a],0,sizeof(chart[a]));
chart[u][c] = a++;
}
u=chart[u][c];
}
if(flag==1) return false;//如果短的号码都是服用于长号码,一定无法打通长的号码
else return true;
}
};
struct str{
char s[11];int len;
void now() {len=strlen(s);}
};
int cmp (str a,str b)
{
return a.len>b.len;
}
str ss[10010];
int main()
{
int t,n,i,flag;
scanf("%d",&t);
while(t--)
{ Trie tmp;
flag=1;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",ss[i].s);
ss[i].now();
}
sort(ss,ss+n,cmp);
for(i=0;i<n;i++)
if(tmp.insert(ss[i].s)==0)
{
flag=0; break;
}
if(flag) printf("YES\n"); else printf("NO\n");
}
return 0;
}
最后C++ 交 4632k 172MS
G++ 4820k 141Ms