nyoj 290 动物统计加强版 <字典树>

本文介绍了一种使用字典树优化动物统计的问题解决方法。面对大量动物名称数据,通过传统排序方法已无法满足效率需求。文章对比了两种实现方式,最终采用字典树结构高效记录并统计出现频率最高的动物名称。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动物统计加强版

时间限制: 3000 ms  |  内存限制: 150000 KB
难度: 4
描述
在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物资料中有未统计数量的原始动物的名单。科学家想判断这片森林中哪种动物的数量最多,但是由于数据太过庞大,科学家终于忍受不了,想请聪明如你的ACMer来帮忙。
输入
第一行输入动物名字的数量N(1<= N <= 4000000),接下来的N行输入N个字符串表示动物的名字(字符串的长度不超过10,字符串全为小写字母,并且只有一组测试数据)。 
输出
输出这些动物中最多的动物的名字与数量,并用空格隔开(数据保证最多的动物不会出现两种以上)。 
样例输入
10
boar
pig
sheep
gazelle
sheep
sheep
alpaca
alpaca
marmot
mole
样例输出
sheep 3
来源
[陈玉 张云聪]原创
上传者
陈玉


一般排序超时,,就用字典树了-.-

-.-记下最大个数及对应的字符串.....


错误代码:TLE,,,,sort排序时间是nlog2  n   是10的8次方左右。。。

 
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
	char hh[12];
	int ll;
}ch[4000100];
bool cmp(node xx,node yy)
{
	if (xx.ll!=yy.ll)
	return xx.ll<yy.ll;
	for (int i=0;i<xx.ll;i++)
	{
		if (i==xx.ll-1)
			return xx.hh[i]<yy.hh[i];
		else
		{
			if (xx.hh[i]!=yy.hh[i])
			return xx.hh[i]<yy.hh[i];
		}
	}
}
int main()
{
	int n;
//	while (~scanf("%d",&n))
//	{
    scanf("%d",&n);
		for (int i=0;i<n;i++)
		{
			scanf("%s",ch[i].hh);
			ch[i].ll=strlen(ch[i].hh);
		}
		sort(ch,ch+n,cmp);
		int s=0,ss=0,lp=0,kk=0;
		strcpy(ch[n].hh,"11111111111");
		ch[n].ll=12;
		for (int i=1;i<=n;i++)
		if (strcmp(ch[i-1].hh,ch[i].hh))
		{
			s=i-lp;
			if (s>ss)
			{
				ss=s;
				kk=lp;
			}
			lp=i;
		}
	//	for (int i=0;i<=n;i++)
	//	printf("666    %s\n",ch[i].hh);
		printf("%s %d",ch[kk].hh,ss);
//	}
	return 0;
}        


错误代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct trie{
	struct trie *chilren[26];
	int lplp;
};
char *ko;//指针 
int s;
struct trie root;
void jia(char xx[])
{
	struct trie *kk;
	kk=&root;
	int ll=strlen(xx);
	for (int i=0;i<ll;i++)
	{
		if (!kk->chilren[xx[i]-'a'])
		{
			kk->chilren[xx[i]-'a']=new trie;
			memset(kk->chilren[xx[i]-'a'],0,sizeof(trie));
			kk->lplp=0;//这是第二个错误....wuwuwu 
		}
		if (i==ll-1)
		{
			kk->lplp=kk->lplp+1;
		    if (s<kk->lplp)
		    {
		    	s=kk->lplp;
		    	ko=xx;
			}
		}
		kk=kk->chilren[xx[i]-'a'];
	}
}
int main()
{
	int n;scanf("%d",&n);
	s=0;
	char lll[12];
	for (int i=0;i<26;i++)
	root.chilren[i]=0;
	root.lplp=0;
	while (n--)
	{
		scanf("%s",lll);
		jia(lll);
	}
	printf("%s %d\n",ko,s);//用指针是最大错误、、因为我指向的是lll,最后一定输出最后那个lll..... 
	return 0;
}

AC代码:

 
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct trie{
	struct trie *chilren[26];
	int lplp;
};
char ko[12];
int s;
struct trie root;
void jia(char xx[])
{
	struct trie *kk;
	kk=&root;
	int ll=strlen(xx);
	for (int i=0;i<ll;i++)
	{
		if (kk->chilren[xx[i]-'a']==NULL)
		{
			kk->chilren[xx[i]-'a']=new trie();
			memset(kk->chilren[xx[i]-'a'],0,sizeof(trie));
			kk->chilren[xx[i]-'a']->lplp=0;
		}
		kk=kk->chilren[xx[i]-'a'];
		if (i==ll-1)
		{
			kk->lplp=kk->lplp+1;
		    if (s<kk->lplp)
		    {
		    	s=kk->lplp;
		    	strcpy(ko,xx);
			}
		}
		
	}
}
int main()
{
	int n;scanf("%d",&n);
	s=0;
	char lll[12];
	for (int i=0;i<26;i++)
	root.chilren[i]=0;
	root.lplp=0;
	while (n--)
	{
		scanf("%s",lll);
		jia(lll);
	}
	printf("%s %d\n",ko,s);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值