zoukankan      html  css  js  c++  java
  • hihoCoder 1260 String Problem I

    时间限制:10000ms
    单点时限:1000ms
    内存限制:256MB

    描写叙述

    我们有一个字符串集合S,当中有N个两两不同的字符串。

    还有M个询问,每一个询问给出一个字符串w。求有多少S中的字符串能够由w加入恰好一个字母得到。

    字母能够加入在包含开头结尾在内的任何位置,比方在"abc"中加入"x",就可能得到"xabc", "axbc", "abxc", "abcx".这4种串。

    输入

    第一行两个数N和M,表示集合S中字符串的数量和询问的数量。

    接下来N行,当中第i行给出S中第i个字符串。

    接下来M行,当中第i行给出第i个询问串。

    全部字符串仅仅由小写字母构成。

    数据范围:

    N,M<=10000。

    S中字符串长度和<=100000。

    全部询问中字符串长度和<=100000。

    输出

    对每一个询问输出一个数表示答案。

    例子输入
    3 3
    tourist
    petr
    rng
    toosimple
    rg
    ptr

    例子输出

     0

     1

     1


      解题思路:

         用字典树做的。将第1个字符串集建树,对第2个字符串。去树上匹配。要在树上跳过1个节点的才是满足条件的,于是就递归枚举跳过的节点即可了。


    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    using namespace std;
    const int maxn=100000+100;
    char s[maxn];
    const int Max=27;
    struct node
    {
        int sign;
        int next[Max];
    } a[maxn];
    set<int> se;
    int cur=0;
    void insert(char *s)
    {
        int len,ans;
        int p=0;
        len=strlen(s);
        for(int i=0; i<len; i++)
        {
            ans=s[i]-'a';
            if(a[p].next[ans]!=0)
            {
                p=a[p].next[ans];
            }
            else
            {
                a[p].next[ans]=++cur;
                a[cur].sign=0;
                p=a[p].next[ans];
            }
        }
        a[p].sign++;
    }
    //int ans;
    int len;
    void find(int sign,int p,int x)
    {
        if(x==len&&sign&&a[p].sign)
        {
           // ans+=a[p].sign;
            se.insert(p);
            //cout<<ans<<endl;
            return;
        }
        if(sign==0&&x<=len)
        {
            for(int i=0; i<26; i++)
            {
                if(a[p].next[i]>0)
                {
                    int tp=a[p].next[i];
                    find(1,tp,x);
                }
            }
        }
        if(x<len)
        {
           int ne=s[x]-'a';
           if(a[p].next[ne]>0)
           {
               int tp=a[p].next[ne];
               find(sign,tp,x+1);
           }
        }
    }
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=0; i<maxn; i++)
            {
                cur=0;
                a[i].sign=0;
                memset(a[i].next,0,sizeof(a[i].next));
            }
            for(int i=0; i<n; i++)
            {
                scanf("%s",s);
                insert(s);
            }
            for(int i=0; i<m; i++)
            {
                se.clear();
                scanf("%s",s);
                len=strlen(s);
                //ans=0;
                find(0,0,0);
                printf("%d
    ",se.size());
            }
    
        }
        return 0;
    }
    


  • 相关阅读:
    EntityFramework 启用迁移 EnableMigrations 报异常 "No context type was found in the assembly"
    JAVA 访问FTP服务器示例(2)
    NuGet Package Manager 更新错误解决办法
    JAVA 访问FTP服务器示例(1)
    RemoteAttribute 的使用问题
    诡异的 javascript 变量
    javascript apply用法
    Babun 中文乱码
    GSM呼叫过程
    转站博客园
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7265149.html
Copyright © 2011-2022 走看看