UVa11732 Strcmp,Anyone?[Trie树]

来源:互联网 发布:朱文臣 的网络与 编辑:程序博客网 时间:2024/05/22 16:43

题目1
题目2
题意:给定判断方式和字符串,输出字符串两两比较的次数;
分析:如果使用正常的字典树,空间复杂度为4000*1000*26,果断爆,但我静态数组没有爆反而RE了,不知道为什么,可能UVa没有MLE?等会试一下;然后还会超时,因为每个节点都要枚举,是4000*1000*26*26,,不过机智一点应该不会超时?就每次insert顺便求了。所以,采用树的压缩算法(左孩子右兄弟)。
第一次写多叉转二叉,本来以为会很麻烦,没想到比普通程序还要短一点,所以基本功要练扎实啊,这些都是基础的。
然后就是经验之谈,在明知道不是正解的情况下,尤其是MLE这么一开始就知道的问题,就不要写程序了,免得浪费自己的时间精力和心情。还有就是调试的时候一定要从逻辑入手,数据是弄不完的,太浪费时间了,理一下自己的思路看有哪些特殊情况没有处理,如果还是找不出来问题再自己举特殊例子调。这种类似递推的题一定要把公式的适用情况和逻辑关系理清楚;
程序:

#include<iostream>    #include<cstdio>    #include<cstring>    #define clr(x) memset(x,0,sizeof(x))    using namespace std;    const int maxn=4000*1000+5;    int fr[maxn],tov[maxn],inde,len,n,cnt;char a[1005],ch[maxn];long long ans,tot[maxn],sig[maxn];void init(){    ans=0;inde=0;clr(fr);clr(tov);clr(tot);clr(ch);clr(sig);}void build(int u,long long dep){    ans+=tot[u]*2LL;    //ans-=sig[u];    if(dep==len){    tot[u]++;    ans+=sig[u];    sig[u]++;    return;}    tot[u]++;    for(int i=fr[u];i;i=tov[i])        if(ch[i]==a[dep]){        build(i,dep+1);return;}    tov[++inde]=fr[u];    fr[u]=inde;    ch[inde]=a[dep];build(inde,dep+1);}int main(){    freopen("UVa11732.in","r",stdin);    freopen("Uva11732.out","w",stdout);    for(scanf("%d",&n);n;scanf("%d",&n)){        init();printf("Case %d: ",++cnt);        for(int i=1;i<=n;i++){            scanf("%s",a);len=strlen(a);build(0,0);        }        printf("%lld\n",ans-tot[0]*(tot[0]-1LL)/2LL);    }    return 0;}
0 0
原创粉丝点击