【UVA】11732 – strcmp() Anyone?

【UVA】11732 – strcmp() Anyone?

大家好,又见面了,我是全栈君。

一開始不知道这样的一维建树方法。

每次一层用一个链指向下一层最左边的结点,之后每一层用一个链表串联全部的结点,这样就建树成功了。

14328524 11732 Accepted C++ 0.826 2014-10-09 13:13:14

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
typedef pair<int,int> pill;
const int nodemaxn = 4000 * 1000 + 100;
struct Trie{
    int head[nodemaxn]; //左儿子链
    int next[nodemaxn]; //右兄弟链
    int   ch[nodemaxn]; //这个结点代表的字符
    LL   tot[nodemaxn]; //有几个单词经过了这个结点
    int   sz;           //结点个数
    LL   ret;           //比較的次数
    void clear(){
        head[0] = 0; next[0] = 0; tot[0] = 0; sz = 1; ret = 0;
    }
    void insert(char *str){
        int L = strlen(str);
        int u = 0,v,found;
        tot[0]++;
        for(int i = 0; i <= L; i ++){
            found = 0;
            for(v = head[u]; v != 0 ; v = next[v]){  //到下一层去找
                if(ch[v] == str[i]){
                    found = 1;
                    break;
                }
            }
            if(!found){  //假设没有找到
                v = sz ++;
                tot[v] = 0;
                ch[v] = str[i];
                next[v] = head[u];
                head[u] = v;
                head[v] = 0;
            }
            u = v;
            tot[u] ++;
        }
    }
    void dfs(int u,int depth){
        if(head[u] == 0){
            ret += tot[u] * (tot[u] - 1) * depth;
        }
        else{
            LL sum = 0;
            for(int v = head[u] ; v != 0; v = next[v])
                sum += tot[v] * (tot[u] - tot[v]);
            ret += sum / 2 * (2 * depth + 1);
            for(int v = head[u] ; v != 0; v = next[v])
                dfs(v,depth + 1);
        }
    }
}trie;
const int maxn = 4000 + 10;
int main(){
    int n,Case = 1;
    while(scanf("%d",&n) && n){
        trie.clear();
        for(int i = 0; i < n; i++){
            char str[maxn];
            scanf("%s",str);
            trie.insert(str);
        }
        trie.dfs(0,0);
        printf("Case %d: %lld\n",Case++,trie.ret);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115603.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Mysql字符串截取[通俗易懂]

    Mysql字符串截取[通俗易懂]Mysql字符串截取函数

    2022年5月7日
    48
  • ES6 数组方法归纳整理

    ES6 数组方法归纳整理ES6操作数组方法1.判断是否为数组 letarr=[1,2,3] console.log(Array.isArray(arr))//true console.log(Array.isArray([]))//true2.创建数组newArray()创建数组如果使用Array构造函数传入一个数值型的值,那么数组的长度length属性会被设置为该值; letitems=newArray(2); console.log(items.length);//2

    2022年6月9日
    32
  • linux杀死进程的五种方法「建议收藏」

    linux杀死进程的五种方法「建议收藏」方法一:Terminal终端输入:gnome-system-monitor,就可以打开systemmonitor如图:然后找到相应进程,右击选择killprocess就可以了方法二:通过kill进程id的方式可以实现,首先需要知道进程id,例如,想要杀死firefox的进程,通过ps-ef|grepfirefox,可以查到firefox的进程

    2022年9月29日
    2
  • 关于SOAP调用返回对象的写法 wsdl webservice

    关于SOAP调用返回对象的写法 wsdl webservice

    2021年5月4日
    145
  • SSH实现远程控制

    SSH(SecureShell)是一种能够提供安全远程登录会话的协议,使用ssh可以在远程linux中执行命令。sshd服务提供两种安全验证的方法:(1)基于口令的安全验证:经过验证帐号与密码即

    2021年12月28日
    45
  • C++多线程并发(五)—原子操作与无锁编程

    C++多线程并发(五)—原子操作与无锁编程一、何为原子操作前面介绍了多线程间是通过互斥锁与条件变量来保证共享数据的同步的,互斥锁主要是针对过程加锁来实现对共享资源的排他性访问。很多时候,对共享资源的访问主要是对某一数据结构的读写操作,如果数据结构本身就带有排他性访问的特性,也就相当于该数据结构自带一个细粒度的锁,对该数据结构的并发访问就能更加简单高效,这就是C++11提供的原子数据类型<atomic>。下面解释两个概念:…

    2022年6月8日
    57

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号