题目链接

/*
简单trie树的应用,注意在初始化的时候要把cnt也初始化,不然,WA!
下面的四分代码各有特点
*/
//数组型,名字查询。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000000;
struct tire{
int wd[27];
int cnt;
void init()
{
cnt=0;
memset(wd,0,sizeof(wd));
}
};
tire tree[maxn];
int tot=1,n,m;
void Insert(char* s,int root)
{
for(int i=0;s[i];i++)
{
int k=s[i]-'a';
if(!tree[root].wd[k])
{
tree[tot].init();
tree[root].wd[k]=tot++;
}
root=tree[root].wd[k];
tree[root].cnt++;
}
}
int sum=0;
int query (int root)
{
int sum=0;
for(int i=0;i<=25;i++)
{
if(tree[root].wd[i])
{
int ro=tree[root].wd[i];
sum+=tree[ro].cnt;
if(tree[ro].cnt>1)
sum+=query(ro);
}
}
return sum;
}
char name[1000000+5];
int main ()
{
int T;scanf("%d",&T);
while(T--)
{
int root=0;
tot=1;
tree[root].init();
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",name);
Insert(name, root);
}
printf("%d\n",query(root));
}
return 0;
}
//指针型,DFS查询
#include<cstdio>
#include<cstring>
#include<iostream>
const int maxn=1000000+5;
const int si=26;
int n;
char name[maxn];
struct node
{
int n;
node *chi[si];
void init()
{
n=0;
for(int i=0;i<si;i++)
chi[i]=NULL;
}
};
void Insert(char *s,node *root)
{
for(int i=0;s[i];i++)
{
if(root->chi[s[i]-'a']==NULL)
{
node *t=(node *)malloc(sizeof(node));
t->init();
root->chi[s[i]-'a']=t;
}
root=root->chi[s[i]-'a'];
root->n++;
}
}
int query(node *root)
{
int sum=0;
for(int i=0;i<si;i++)
{
if(root->chi[i]!=NULL)
{
node *t=root->chi[i];
sum+=t->n;
if(t->n>=2)
sum+=query(t);
}
}
return sum;
}
void rease(node *root)
{
for(int i=0;i<si;i++)
{
if(root->chi[i]!=NULL)
rease(root->chi[i]);
}
delete root;
}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
int n=0;
scanf("%d",&n);
node *root=(node *)malloc(sizeof(node));
root->init();
for(int i=0;i<n;i++)
{
scanf("%s",name);
Insert(name, root);
}
printf("%d\n",query(root));
}
}
//数组型,DFS查询
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1000000;
struct tire{
int wd[27];
int cnt;
void init()
{
cnt=0;
memset(wd,0,sizeof(wd));
}
};
tire tree[maxn];
int tot=1,n,m;
void Insert(char* s,int root)
{
for(int i=0;s[i];i++)
{
int k=s[i]-'a';
if(!tree[root].wd[k])
{
tree[tot].init();
tree[root].wd[k]=tot++;
}
root=tree[root].wd[k];
tree[root].cnt++;
}
}
int sum=0;
int query (int root)
{
int sum=0;
for(int i=0;i<=25;i++)
{
if(tree[root].wd[i])
{
int ro=tree[root].wd[i];
sum+=tree[ro].cnt;
if(tree[ro].cnt>1)
sum+=query(ro);
}
}
return sum;
}
char name[1000000+5];
int main ()
{
int T;scanf("%d",&T);
while(T--)
{
int root=0;
tot=1;
tree[root].init();
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%s",name);
Insert(name, root);
}
printf("%d\n",query(root));
}
return 0;
}
//数组型,名字查询,名字在string中保存,虽然可以节约空间,但是由于string只能用cin输入,所以时间慢。
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
const int maxn=1000000;
struct tire
{
int wd[27];
int cnt;
void init()
{
cnt=0;
memset(wd,0,sizeof(wd));
}
};
tire tree[maxn];
int tot=1,n,m;
void Insert(string s,int root)
{
for(int i=0;s[i];i++)
{
int k=s[i]-'a';
if(!tree[root].wd[k])
{
tree[tot].init();
tree[root].wd[k]=tot++;
}
root=tree[root].wd[k];
tree[root].cnt++;
}
}
int query (string s,int root)
{
for(int i=0;s[i];i++)
{
int k=s[i]-'a';
root=tree[root].wd[k];
if(tree[root].cnt==1)
return i+1; }
return tree[root].cnt+1;
}
string name[1000+5];
int main ()
{
int T;scanf("%d",&T);
while(T--)
{
int root=0;
tot=1;
tree[root].init();
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>name[i];
Insert( name[i], root);
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans+=query(name[i], root);
}
printf("%d\n",ans);
}
return 0;
}

Trie/最短的名字的更多相关文章

  1. csuoj 1115: 最短的名字

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1115 1115: 最短的名字 Time Limit: 5 Sec  Memory Limit: 6 ...

  2. CSU 1115 最短的名字

    传送门 Time Limit: 5000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu Description 在一个奇怪的 ...

  3. E - 最短的名字

    Description 在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫'aaa ...

  4. CSU - 1115 最短的名字(字典树模板题)

    Description 在一个奇怪的村子中,很多人的名字都很长,比如aaaaa, bbb and abababab. 名字这么长,叫全名显然起来很不方便.所以村民之间一般只叫名字的前缀.比如叫'aaa ...

  5. 2012年湖南省程序设计竞赛E题 最短的名字

    题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1115 解题报告:输入n个字符串,让你求出可以用来区别这些字符串的最少的前缀总共有多少个字 ...

  6. 6天通吃树结构—— 第五天 Trie树

    原文:6天通吃树结构-- 第五天 Trie树 很有段时间没写此系列了,今天我们来说Trie树,Trie树的名字有很多,比如字典树,前缀树等等. 一:概念 下面我们有and,as,at,cn,com这些 ...

  7. 内存空间有限情况下的词频统计 Trie树 前缀树

    数据结构与算法专题--第十二题 Trie树 https://mp.weixin.qq.com/s/nndr2AcECuUatXrxd3MgCg

  8. 湖南省第八届大学生计算机程序设计竞赛(A,B,C,E,F,I,J)

    A 三家人 Description 有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园.A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕.C 太太因为正身怀六甲无法加入她们的行列, ...

  9. LINQ之路 7:子查询、创建策略和数据转换

    在前面的系列中,我们已经讨论了LINQ简单查询的大部分特性,了解了LINQ的支持计术和语法形式.至此,我们应该可以创建出大部分相对简单的LINQ查询.在本篇中,除了对前面的知识做个简单的总结,还会介绍 ...

随机推荐

  1. Java Object 引用传递和值传递

    Java Object 引用传递和值传递 @author ixenos Java没有引用传递: 除了在将参数传递给方法(或函数)的时候是"值传递",传递对象引用的副本,在任何用&q ...

  2. 清除js-css缓存,清除app缓存,清除php缓存

    入口文件,定义版本常量 define('VERSION','version=002');//自定义版本号 html文件引用常量 <script src="/js/detail.js?& ...

  3. IOS CrackMe 破解学习

    一直在看别人如何破解一个app,下面自己也尝试着学习怎么去破解一个app的密码,下面是完整的过程. 准备工作: 一台mac或者pc安装了ssh客户端 一台越狱的iphone iphone上安装了ope ...

  4. DOS 命令批量删除文件及相关批处理命令详解

    del X:\*.* /f /s /q /a 递归强制静默删除X盘及其所有子目录下的所有文件 /f 表示强制删除文件 /s表示子目录都要删除该文件 /q表示无声,不提示 /a根据属性选择要删除的文件 ...

  5. oracle 序列介绍

    序列介绍 序列是一个计数器,它并不会与特定的表关联.通过创建Oracle序列和触发器实现表的主键自增. 序列的用途一般用来填充主键和计数. 序列使用 1.创建序列 ORACLE序列的语法格式为: CR ...

  6. android代码格式化方法小结

    转载:http://blog.csdn.net/androidzhaoxiaogang/article/details/7692526 Download the android-formatting. ...

  7. ios简单实现如果没有开启定位,提示开启系统软件定位功能

    if([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == ...

  8. MFC中将编辑框文本转换成整数,从而实现两个整数相加。

    在头文件中,定义三个控件变量,如m_data1,m_data2,m_sum; void Cuse_demo_dllDlg::OnBnClickedButton1(){ CString data1; C ...

  9. ASP.NET—013:实现带控件的弹出层(弹出框)

    http://blog.csdn.net/yysyangyangyangshan/article/details/38458169 在页面中用到弹出新页面的情况比较多的,一般来说都是使用JS方法sho ...

  10. hdu_3068_最长回文(Manacher)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3068 题意:给你一个字符串,让你求最长的回文子串. 题解:数据量比较大,暴力O(n2)会超时,直接上马 ...