zoukankan      html  css  js  c++  java
  • codeforces613E

    Puzzle Lover

     CodeForces - 613E 

    Oleg Petrov loves crossword puzzles and every Thursday he buys his favorite magazine with crosswords and other word puzzles. In the last magazine Oleg found a curious puzzle, and the magazine promised a valuable prize for it's solution. We give a formal description of the problem below.

    The puzzle field consists of two rows, each row contains n cells. Each cell contains exactly one small English letter. You also are given a word w, which consists of ksmall English letters. A solution of the puzzle is a sequence of field cells c1..., ck, such that:

    • For all i from 1 to k the letter written in the cell ci matches the letter wi;
    • All the cells in the sequence are pairwise distinct;
    • For all i from 1 to k - 1 cells ci and ci + 1 have a common side.

    Oleg Petrov quickly found a solution for the puzzle. Now he wonders, how many distinct solutions are there for this puzzle. Oleg Petrov doesn't like too large numbers, so calculate the answer modulo 109 + 7.

    Two solutions ci and c'i are considered distinct if the sequences of cells do not match in at least one position, that is there is such j in range from 1 to k, such that cj ≠ c'j.

    Input

    The first two lines contain the state of the field for the puzzle. Each of these non-empty lines contains exactly n small English letters.

    The next line is left empty.

    The next line is non-empty and contains word w, consisting of small English letters.

    The length of each line doesn't exceed 2 000.

    Output

    Print a single integer — the number of distinct solutions for the puzzle modulo 109 + 7.

    Examples

    Input
    code
    edoc

    code
    Output
    4
    Input
    aaa
    aaa

    aa
    Output
    14

    sol:超好的一道dp题
    事实上我代码和上面略有不同
    提醒一下:注意一点就是不要算重,比如要向左或向右绕一圈回来的时候一圈的长度最小值为4,因为直接往下走的话在中间那段的转移中已经算过了
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    
    const int N=2005;
    const ll Base=97,Mod=1000000007;
    int n,Len;
    char S[2][N],T[N];
    inline void Ad(ll &x,ll y)
    {
        x+=y; x-=(x>=Mod)?Mod:0;
    }
    ll Seed[N];
    inline void Prepare(int n)
    {
        int i; Seed[0]=1;
        for(i=1;i<=n;i++) Seed[i]=1ll*Seed[i-1]*Base%Mod;
    }
    struct Hash
    {
        ll Hash[N];
        inline void Make(int n,char *S)
        {
            int i; Hash[0]=0; for(i=1;i<=n;i++) Hash[i]=(Hash[i-1]*Base%Mod+(S[i]-'a'+1))%Mod;
        }
        inline ll Ask(int l,int r)
        {
            return (ll)(Hash[r]+Mod-Hash[l-1]*Seed[r-l+1]%Mod)%Mod;
        }
    }Pre[2],Suf[2],HT;
    ll dp[2][N][N];
    //dp[i][j][k]表示在第i行,第j-1个(即i,j在当前点右边),已经匹配了k为的方案数 
    inline ll Solve(bool opt)
    {
        ll res=0;
        int i,j,k;
        memset(dp,0,sizeof dp);
        for(j=1;j<=n;j++)
        {
            dp[0][j][0]=dp[1][j][0]=1;
            for(i=0;i<=1;i++) for(k=2;k<=min(n-j+1,Len/2);k++) //向右绕一圈回来 
            {
                if(Pre[i].Ask(j,j+k-1)==HT.Ask(Len-2*k+1,Len-k)&&Suf[i^1].Ask(n-(j+k-1)+1,n-j+1)==HT.Ask(Len-k+1,Len))
                {
                    if((k*2!=Len)||opt) Ad(res,dp[i][j][Len-k*2]);
                }
            }
            for(i=0;i<=1;i++) for(k=2;k<=min(j,Len/2);k++) //向左绕一圈回来 
            {
                if(Suf[i].Ask(n-j+1,n-(j-k+1)+1)==HT.Ask(1,k)&&Pre[i^1].Ask(j-k+1,j)==HT.Ask(k+1,k*2))
                {
                    if((k*2!=Len)||opt) Ad(dp[i^1][j+1][k*2],1);
                }
            }
            for(i=0;i<=1;i++) for(k=1;k<=Len;k++)
            {
                if(T[k]==S[i][j])
                {
                    Ad(dp[i][j+1][k],dp[i][j][k-1]);
                    if(k<Len&&T[k+1]==S[i^1][j])
                    {
                        Ad(dp[i^1][j+1][k+1],dp[i][j][k-1]);            
                    }
                }
            }
            for(i=0;i<=1;i++) Ad(res,dp[i][j+1][Len]);
        }
        return res;
    }
    int main()
    {
        ll i,j,ans=0;
        Prepare(2000);
        scanf("%s",S[0]+1); n=strlen(S[0]+1); scanf("%s",S[1]+1); scanf("%s",T+1); Len=strlen(T+1);
        for(i=0;i<=1;i++)
        {
            Pre[i].Make(n,S[i]); reverse(S[i]+1,S[i]+n+1); Suf[i].Make(n,S[i]); reverse(S[i]+1,S[i]+n+1);
        }
        HT.Make(Len,T);
        Ad(ans,Solve(1));
        if(Len>1)
        {
            reverse(T+1,T+Len+1); HT.Make(Len,T); Ad(ans,Solve(0));
        }
        if(Len==2)
        {
            for(j=1;j<=n;j++) for(i=0;i<=1;i++) if(S[i][j]==T[1]&&S[i^1][j]==T[2]) Ad(ans,Mod-1);
        }
        Wl(ans);
        return 0;
    }
    /*
    input
    code
    edoc
    code
    output
    4
    
    input
    aaa
    aaa
    aa
    output
    14
    
    input
    v
    s
    sv
    output
    1
    */
    View Code
    
    
    
     
  • 相关阅读:
    服务器的Redis连接不上解决方案
    给大家推荐一个很好的自学网站
    简单说下HashMap的实现原理
    LinkedList源码解析
    你要了解的jvm
    单例设计
    百度编辑器删除旧的图片
    Ueditor 单图、多图、视频、附件的上传及在线管理总结
    上传新图片删除旧图片
    webapi发布IIS时出现500.19错误:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的(overrideModeDefault="Deny")或者是通过包含overrideModeDefault="Deny"....
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/11167205.html
Copyright © 2011-2022 走看看