现在的位置: 首页 > 综合 > 正文

POJ 3630 静态字典树

2013年08月12日 ⁄ 综合 ⁄ 共 1191字 ⁄ 字号 评论关闭

题意:给你一些电话号码,问你是否有一个电话号码是其他电话号码前缀

比如,911 和911584这两个号码,911是911584的前缀

解题思路:经过pork大神的指导,估计时间如下,一共有10000个电话号码插入,每个号码最长10位,如果每次插入最差就是开辟10个新的节点,那就是10000*10*10个,一百W,如果有new开辟的话,时间耗费严重,超时是必然的,那么用静态数组,提前开辟100W个,用的时候就把它提出来。

检测的时候先按长度排序,举个discuss的反例

2
2
1
12
2
12
1
NO
NO

必须先保证长度小的先被插入字典树里面,这样长度长的才能检测出来

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
struct Dictree
{
	bool in;
	struct Dictree *next[10];
}node[1000000];
Dictree root;
int cmp(const void *a,const void *b)
{
	char *p1,*p2;
	p1=(char *)a;
	p2=(char *)b;
	return strlen(p1)-strlen(p2);
}
int tot;
char s[10005][12];
bool reflect;
void create_tree();
void insert(char *);
int main()
{
	int cas,n,i;
	for(scanf("%d",&cas);cas;cas--)
	{
		reflect=false;
		create_tree();
		scanf("%d",&n);
		for(i=0;i<n;i++)
			scanf("%s",s[i]);
		qsort(s,n,sizeof(s[0]),cmp);
		for(i=0;i<n;i++) 
			if(!reflect) insert(s[i]);
		if(reflect) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
void create_tree()
{
	root.in=false;
	tot=0;
	memset(root.next,NULL,sizeof(root.next));
}
void insert(char *s)
{
	int i;
	struct Dictree *p;
	p=&root;
	for(i=0;s[i];i++)
	{
		if(p->next[s[i]-'0']==NULL)
		{
			node[tot].in=false;
			memset(node[tot].next,NULL,sizeof(node[tot].next));
			p->next[s[i]-'0']=&node[tot++];
		}
		p=p->next[s[i]-'0'];
		if(p->in) reflect=true;
	}
	p->in=true;
}

抱歉!评论已关闭.