zoukankan      html  css  js  c++  java
  • UVA

    input

    n 2<=n<=4000

    s1

    s2

    ...

    sn

    1<=len(si)<=1000

    output

    输出用strcmp()两两比较si,sj(i!=j)要比较的次数,结果在long long范围内(相同字符比较两次,不相同字符比较一次,包括'')

    做法:由于字符集太大,要用左兄弟右儿子的trie保存字符,不用每次都开ch[62]个孩子

     1 #include <cstdio>
     2 #include <queue>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <map>
     9 #include <set>
    10 #include <ctime>
    11 #include <cmath>
    12 #include <cctype>
    13 #define MAX 100000
    14 #define LL long long
    15 #define mod 20071027
    16 struct node
    17 {
    18     int sz;
    19     char val;
    20     node*ch[2];            //ch[1]兄弟,ch[0]儿子
    21     node()
    22     {
    23         ch[0]=ch[1]=NULL;
    24         sz=0;
    25     }
    26 };
    27 char word[1010];
    28 int n,cas=1;
    29 long long sum;
    30 long long insert(char*s,node*u)
    31 {
    32     long long sum=0,lastsz=u->sz++;
    33     for(;*s||*(s-1);s++)
    34     {
    35         if(!u->ch[0])            //易错,要先把新建的结点连接到父结点才能往下走,否则新建之后父节点无法再读取到该结点
    36         {
    37             u->ch[0]=new node;
    38             u->ch[0]->val=*s;
    39         }    
    40         for(u=u->ch[0];u->val!=*s;u=u->ch[1])
    41         {
    42             if(!u->ch[1])
    43             {
    44                 u->ch[1]=new node;
    45                 u->ch[1]->val=*s;
    46             }
    47         }    
    48         sum+=lastsz+u->sz;
    49         lastsz=u->sz++;
    50     }
    51     return sum;
    52 }
    53 /*//这样可以将父节点的ch和新建的结点绑定起来,传过来的是&root
    54 long long insert(char*s,node**u)
    55 {
    56     long long sum=0,lastsz=(*u)->sz++;
    57     for(;*s||*(s-1);s++)
    58     {
    59         printf("%p
    ",u);
    60         for(u=&((*u)->ch[0]);(*u)&&(*u)->val!=*s;u=&((*u)->ch[1]));
    61         if(*u==NULL)
    62         {
    63             *u=new node;
    64             (*u)->ch[0]=(*u)->ch[1]=NULL;
    65             (*u)->val=*s;
    66         }
    67         sum+=lastsz+(*u)->sz;
    68         lastsz=(*u)->sz++;
    69     }
    70     return sum;
    71 }*/
    72 void freenode(node*u)
    73 {
    74     if(u==NULL) return;
    75     freenode(u->ch[0]);
    76     freenode(u->ch[1]);
    77     delete u;
    78 }
    79 int main()
    80 {
    81     //freopen("/home/user/桌面/in","r",stdin);
    82     while(scanf("%d",&n)==1&&n)
    83     {
    84         sum=0;
    85         node *root=new node;
    86         while(n--)
    87         {
    88             scanf("%s",word);
    89             sum+=insert(word,root);
    90         }
    91         printf("Case %d: %lld
    ",cas++,sum);
    92         freenode(root);
    93     }
    94     //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
    95     return 0;
    96 }
    97 
    98 my Code
    my Code
     1 #include <cstdio>  
     2 #include <cstring>  
     3 #include <iostream>  
     4 #include <algorithm>  
     5 using namespace std;  
     6   
     7 #define repf(i,a,b) for(int i=(a);i<=(b);i++)  
     8 typedef long long ll;  
     9   
    10 const int N = 0;  
    11 const int MAXNODE = 4000010;  
    12   
    13 int n, cas;  
    14 ll ans;  
    15 char str[4001];  
    16   
    17 struct STrie {  
    18     int son[MAXNODE];  
    19     int bro[MAXNODE];  
    20     int val[MAXNODE];  
    21     char ch[MAXNODE];  
    22     int sz;  
    23   
    24     STrie() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
    25     void init() { sz = 1; ch[0] = val[0] = bro[0] = son[0] = 0; }  
    26     // inline int idx(char c) { return c - 'a'; }  
    27       
    28     void insert(char *s) {  
    29         int len = strlen(s), u = 0, p;  
    30         repf (i, 0, len) {  
    31             // check the brother of u  
    32             for (p = son[u]; p; p = bro[p]) {  
    33                 if (ch[p] == s[i])  
    34                     break;  
    35             }  
    36             // cannot find out than insert  
    37             if (!p) {  
    38                 p = sz++;  
    39                 ch[p] = s[i];  
    40                 bro[p] = son[u];  
    41                 son[p] = 0;  
    42                 val[p] = 0;  
    43                 son[u] = p;  
    44             }  
    45             ans += (val[u] - val[p]) * (2 * i + 1);  
    46             if (len == i) {  
    47                 ans += val[p] * (2 * i + 2);  
    48                 val[p]++;  
    49             }  
    50             val[u]++;  
    51             u = p;  
    52         }  
    53     }  
    54 } trie;  
    55   
    56 int main() {  
    57     // ios_base::sync_with_stdio(0);  
    58     while (~scanf("%d", &n) && n) {  
    59         trie.init();  
    60         ans = 0;  
    61         repf (i, 0, n - 1) {  
    62             scanf("%s", str);  
    63             trie.insert(str);  
    64         }  
    65         printf("Case %d: %lld
    ", ++cas, ans);  
    66     }  
    67     return 0;  
    68 } 
    copy Code
  • 相关阅读:
    dhtmlTree简单实例以及基本参数设置
    ewebeditor上传文件大小
    Java中集合类
    Ibatis入门基本语法
    afinal 上传文件服务端接受参数为空
    Android的快速开发框架 afinal
    学习asp.net比较完整的流程
    android中sharedPreferences的用法
    mysql怎样配置ODBC数据源
    细谈虚拟主机常见问题
  • 原文地址:https://www.cnblogs.com/cdyboke/p/5015540.html
Copyright © 2011-2022 走看看