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