zoukankan      html  css  js  c++  java
  • Substring

    Substring

    Given a set of pattern strings, and a text, you have to find, if any of the pattern is a substring of the text. If any of the pattern string can be found in text, then print “yes”, otherwise “no” (without quotes).

    But, unfortunately, that’s not what is asked here. J

    The problem described above, requires a input file generator. The generator generates a text of length L, by choosing L characters randomly. Probability of choosing each character is given as priori, and independent of choosing others.

    Now, given a set of patterns, calculate the probability of a valid program generating “no”.

    Input

    First line contains an integer T, the number of test cases. Each case starts with an integer K, the number of pattern strings. Next K lines each contain a pattern string, followed by an integer N, number of valid characters.  Next N lines each contain a character and the probability of selecting that character, pi. Next an integer L, the length of the string generated. The generated text can consist of only the valid characters, given above.

    There will be a blank line after each test case.

    Output

    For each test case, output the number of test case, and the probability of getting a “no”.

    Constraints

    ·         T  ≤ 50

    ·         K ≤ 20

    ·        Length of each pattern string is between 1 and 20

    ·        Each pattern string consists of only alphanumeric characters (‘a’ to ‘z’, ‘A’ to ‘Z’,’0’ to ‘9’)

    ·        Valid characters are all alphanumeric characters

    ·        ∑pi = 1

    ·        L ≤ 100

    Sample input

    2

    1

    a

    2

    a 0.5

    b 0.5

    2

    2

    ab

    ab

    2

    a 0.2

    b 0.8

    2

    分析:ac自动机+dp;

       dp[i][j]表示到i节点剩余j长度的概率,则dp[i][j]+=p[j]*dp[ch[i][k]][j-1];

       记忆化搜索优化;

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <cstring>
    #include <string>
    #include <set>
    #include <map>
    #include <unordered_map>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <list>
    #define rep(i,m,n) for(i=m;i<=n;i++)
    #define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
    #define mod 1000000007
    #define inf 0x3f3f3f3f
    #define vi vector<int>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define ll long long
    #define pi acos(-1.0)
    #define pii pair<int,int>
    #define Lson L, mid, ls[rt]
    #define Rson mid+1, R, rs[rt]
    #define sys system("pause")
    #define intxt freopen("in.txt","r",stdin)
    const int maxn=1e5+10;
    using namespace std;
    ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
    ll qpow(ll p,ll q){ll f=1;while(q){if(q&1)f=f*p;p=p*p;q>>=1;}return f;}
    inline ll read()
    {
        ll x=0;int f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,m,k,t,cas,vis[maxn][105];
    char a[maxn];
    double p[maxn],q[maxn][105];
    struct node
    {
        int ch[maxn][65],f[maxn],val[maxn],last[maxn],cnt[maxn],sz;
        void init()
        {
            sz=0;
            memset(ch[0],0,sizeof(ch[0]));
            memset(cnt,0,sizeof(cnt));
        }
        //字符编号;
        int idx(char x)
        {
            if(x>='0'&&x<='9')return x-'0';
            else if(x>='A'&&x<='Z')return x-'A'+10;
            else if(x>='a'&&x<='z')return x-'a'+36;
        }
        //插入字符串,v非0;
        void insert(char *p,int v)
        {
            int pos=0;
            for(int i=0;p[i];i++)
            {
                int x=idx(p[i]);
                if(!ch[pos][x])
                {
                    ch[pos][x]=++sz;
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=0;
                }
                pos=ch[pos][x];
            }
            val[pos]=1;
        }
        //递归打印以结点x结尾的所有字符串;
        void out(int x)
        {
            if(x)
            {
                cnt[val[x]]++;
                out(last[x]);
            }
        }
        //找模板;
        void find(char *p)
        {
            int pos=0;
            for(int i=0;p[i];i++)
            {
                int x=idx(p[i]);
                pos=ch[pos][x];
                if(val[pos])out(pos);
                else if(last[pos])out(last[pos]);
            }
        }
        //fail函数;
        void fail()
        {
            queue<int>p;
            f[0]=0;
            //初始化;
            for(int i=0;i<65;i++)
            {
                int x=ch[0][i];
                if(x)f[x]=0,p.push(x),last[x]=0;
            }
            //bfs计算fail;
            while(!p.empty())
            {
                int x=p.front();
                p.pop();
                for(int i=0;i<65;i++)
                {
                    int y=ch[x][i];
                    if(!y)
                    {
                        ch[x][i]=ch[f[x]][i];
                        continue;
                    }
                    p.push(y);
                    int v=f[x];
                    while(v&&!ch[v][i])v=f[v];
                    f[y]=ch[v][i];
                    last[y]=val[f[y]]?f[y]:last[f[y]];
                    val[y]|=val[f[y]];
                }
            }
        }
    }ac;
    double gao(int x,int y)
    {
        if(!y)return 1.0;
        if(vis[x][y])return q[x][y];
        vis[x][y]=1;
        double &ans=q[x][y];
        ans=0.0;
        for(int i=0;i<65;i++)
        {
            if(!ac.val[ac.ch[x][i]])ans+=p[i]*gao(ac.ch[x][i],y-1);
        }
        return ans;
    }
    int main()
    {
        int i,j;
        scanf("%d",&t);
        while(t--)
        {
            ac.init();
            rep(i,0,64)p[i]=0;
            memset(vis,0,sizeof(vis));
            scanf("%d",&n);
            rep(i,1,n)
            {
                scanf("%s",a);
                ac.insert(a,i);
            }
            ac.fail();
            scanf("%d",&n);
            rep(i,1,n)
            {
                double x;
                scanf("%s%lf",a,&x);
                p[ac.idx(a[0])]=x;
            }
            scanf("%d",&m);
            printf("Case #%d: %.6f
    ",++cas,gao(0,m));
        }
        //system("Pause");
        return 0;
    }
  • 相关阅读:
    js查找字符串中重复的子字符串
    未知盒子宽高使盒子垂直水平居中
    标准盒模型和怪异盒模型的差异
    Vue练习(跑马灯效果)
    node后端中MVC与前端中的MVVM之间的区别
    ES6中对Promise解析
    ES6中对箭头函数的使用
    ES6对map解析
    ES6中对Set解析
    ES6解构赋值全了解
  • 原文地址:https://www.cnblogs.com/dyzll/p/6076893.html
Copyright © 2011-2022 走看看