zoukankan      html  css  js  c++  java
  • uva 11732 "strcmp()" Anyone?

    https://vjudge.net/problem/UVA-11732

    题意:

    给出许多字符串,他们两两按下面的函数比较

    输出比较次数

    s[i]==t[i]  ,  和  s[i]==''   各算一次比较 

     法一:

    每两个字符串,要么全部匹配,要么中间停止匹配

    如果全部匹配,比较次数为 2*len+2(‘’两次匹配)

    如果中间停止匹配,比较次数为 2*相同前缀长度+1 (1次失败匹配后退出)

    所以

    1、对于第i个字符串,先加上i-1,即假设全部 中间停止匹配

    这样最后再加上全部匹配数

    2、匹配一个就+sum*2

    #include<cstdio>
    #include<cstring>
    #define N 1001
    using namespace std;
    
    char s[N];
    int sum[N*4001],len,trie[N*4001][63],tot;
    long long ans;
    int mark[N*4001];
    
    int get(int i)
    {
        if(s[i]>='0'&&s[i]<='9') return s[i]-'0';
        if(s[i]>='a'&&s[i]<='z') return s[i]-'a'+10;
        if(s[i]>='A'&&s[i]<='Z') return s[i]-'A'+36;
    }
    void insert(int cnt)
    {
        int root=0,id;
        ans+=cnt;
        for(int i=0;i<len;i++)
        {
            id=get(i);
            if(!trie[root][id]) 
            {
                trie[root][id]=++tot;
                memset(trie[tot],0,sizeof(trie[tot]));
                sum[tot]=mark[tot]=0;
            }
            root=trie[root][id];
            ans+=sum[root]<<1;
            sum[root]++;
        }
        ans+=mark[root];
        mark[root]++;
    }
    int main()
    {
        int n,t=0;
        while(scanf("%d",&n)!=EOF)
        {
            if(!n) return 0;
            memset(trie[0],0,sizeof(trie[0]));
            ans=0;tot=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                len=strlen(s);
                insert(i-1);
            }
            printf("Case %d: %lld
    ",++t,ans);
        }
    }
    View Code

    法二:

    用cnt记录现在还剩下几个是匹配的

    那么每次

    1、ans+=cnt-sum 匹配失败

    2、ans+=sum*2  匹配成功

    3、cnt=sum 

    注意:为了好处理,所以字符串的结束符也算上了

    那么这就要循环到len,另外特殊给‘’赋一个id

    #include<cstdio>
    #include<cstring>
    #define N 1001
    using namespace std;
    
    char s[N];
    int sum[N*4001],len,trie[N*4001][63],tot;
    long long ans;
    
    int get(int i)
    {
        if(s[i]>='0'&&s[i]<='9') return s[i]-'0';
        if(s[i]>='a'&&s[i]<='z') return s[i]-'a'+10;
        if(s[i]>='A'&&s[i]<='Z') return s[i]-'A'+36;
        return 62;
    }
    void insert(int cnt)
    {
        int root=0,id;
        for(int i=0;i<=len;i++)
        {
            id=get(i);
            if(!trie[root][id]) 
            {
                trie[root][id]=++tot;
                memset(trie[tot],0,sizeof(trie[tot]));
                sum[tot]=0;
            }
            root=trie[root][id];
            ans+=cnt-sum[root];
            ans+=sum[root]<<1;
            cnt=sum[root];
            sum[root]++;
        }
    }
    int main()
    {
        int n,t=0;
        while(scanf("%d",&n)!=EOF)
        {
            if(!n) return 0;
            memset(trie[0],0,sizeof(trie[0]));
            ans=0;tot=0;
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                len=strlen(s);
                insert(i-1);
            }
            printf("Case %d: %lld
    ",++t,ans);
        }
    }
    View Code
  • 相关阅读:
    gauss消元
    POJ1229 域名匹配
    HDU3487 play with chain
    POJ1185 炮兵阵地
    POJ2411
    sgu233 little kings
    树形DP初步-真树1662
    树形DP初步-二叉树1661
    c++——string类用法
    UVa1354 ——天平难题
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6958455.html
Copyright © 2011-2022 走看看