题目链接:https://vjudge.net/contest/158125#problem/A

题意:

系统中,strcmp函数是这样执行的,给定 n 个字符串,求两两比较时,strcmp函数要比较多少次?

如:

t  h  a  n  \n       t  h  e  r  e  \n

t  h  a  t  \n        t  h  e  \n

2  2  2  1            2  2  2  1

直接两两比较是超时的。

可以这样建立一个字典树:

可以发现一直要比较到交叉处,和这个交叉点的深度有关(2*depth+1)。

1、这个字典序每一个交叉点都是要计算的,所以采用邻接表的形式存图;

2、每个结点都要计算他的叶子结点的个数,当分叉的时候,那么说明这里有两个(多个)不同的单词,从中要选择两个单词,计算有多少种搭配,比较次数就是这些搭配*(2*depth+1);

3、递归找下一个结点。

 #include <bits/stdc++.h>

 using namespace std;

 const int maxnode =  *  + ;
const int sigma_size = ; struct Trie
{
int head[maxnode];
int next[maxnode];
char ch[maxnode];
int tot[maxnode];
int sz;
long long ans;
void clear()
{
sz = ;
tot[] = head[] = next[] = ;
} void insert(const char *s)
{
int u = , v, n = strlen(s);
tot[]++;
for(int i = ; i <= n; i++)
{
// 找字符a[i]
bool found = false;
for(v = head[u]; v != ; v = next[v])
if(ch[v] == s[i]) // 找到了
{
found = true;
break;
}
if(!found)
{
v = sz++; // 新建结点
tot[v] = ;
ch[v] = s[i];
next[v] = head[u];
head[u] = v; // 插入到链表的首部
head[v] = ;
}
u = v;
tot[u]++;
}
} void dfs(int depth,int u)
{
if(head[u]==) //叶子节点
ans+=tot[u]*(tot[u]-)*depth;
else
{
int sum =;
for(int v=head[u]; v!=; v=next[v])
{
sum+=tot[v]*(tot[u]-tot[v]);
}
ans+=sum/*(*depth+);
for(int v=head[u]; v!=; v=next[v])
dfs(depth+,v);
}
} long long count()
{
ans = ;
dfs(,);
return ans;
} } trie; char word[]; int main()
{
int n;
int kase = ;
while(scanf("%d",&n),n)
{
trie.clear();
for(int i=; i<n; i++)
{
scanf("%s",word);
trie.insert(word);
}
printf("Case %d: %lld\n",kase++,trie.count());
} return ;
}

最新文章

  1. 错题分析--ASP.NET
  2. 如何让Hadoop读取以gz结尾的文本格式的文件
  3. MIT 6.824 : Spring 2015 lab1 训练笔记
  4. TRUNK的作用功能.什么是TRUNK
  5. 常用的 DOCTYPE 声明
  6. WindowsForm应用程序调用WebService
  7. winform - BackgroundWorker
  8. iOS 全局竖屏 单个viewcontroller点击按钮支持横屏
  9. ios显示艺术字字体颜色渐变
  10. WCF方式调用asmx设置cookie
  11. C#语言基础之转义字符、变量、常量、类型转换
  12. WPF程序长时间无人操作
  13. Python第一天 安装 shell 文件
  14. 三、ASP.NET MVC Controller 控制器(二:IController控制器的创建过程)
  15. Struts 2 之文件上传
  16. 使用Fiddler获取OAuth2认证的access token时候返回502
  17. CardView卡片式布局
  18. linux 系统管理11 ——系统安全及应用
  19. js将一维数组转化为二维数组
  20. My_SQ主键,外键

热门文章

  1. centos 7 安装 最小化 碰到的问题
  2. Java学习笔记day04_数组
  3. GO 日志追加记录
  4. python 安装 第三方包
  5. 数据库版本管理工具flyway
  6. Android中的APinner2
  7. Java学生管理系统(连接数据库查询)超详细
  8. DEDE日期调用小插件
  9. Quartz使用(5) - Quartz的Job存储及集群部署
  10. 移动Web开发与适配笔记