• 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;
    }
    


  • 相关阅读:
    java JDBC (一)
    java 线程(七)等待与唤醒
    java 线程(六)死锁
    java 线程(五)线程安全 Lock接口
    java 线程(四)线程安全 同步方法
    查询计算机启动了多长时间的工具
    查询计算机启动了多长时间的工具
    百度同步盘无法登陆,报错155010,对策
    百度同步盘无法登陆,报错155010,对策
    锁屏工具,解决三星S7迷你锁屏后不能通过指纹解锁的问题
  • 原文地址:https://www.cnblogs.com/mthoutai/p/7265149.html
Copyright © 2020-2023  润新知