HDOJ 5763 Another Meaning

来源:互联网 发布:软件开发 需求文档 编辑:程序博客网 时间:2024/06/05 21:52

题意

给两个字符串a和b,b有两义性,求a一共有多少种可能的意思。

思路

首先KMP预处理出所有b是a子串的末尾位置,然后基础dp就可以了。
如果i位置是子串末尾则dp[i] = dp[i-1] + dp[i-lenb] + 1否则直接转移。

代码

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <bitset>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 1e5 + 7;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;bool ok[maxn];int dp[maxn];char a[maxn], b[maxn];void getnext(char *p, int n, int *next){    int i = 0, j = -1;    next[0] = j;    while (i < n)    {        while (j != -1 && p[j] != p[i])            j = next[j];        i++, j++;        if (j >= n)            next[i] = next[j-1];        else            next[i] = j;    }}void kmp(char *p, int n, char *s, int m){    int next[10005];    getnext(p, n, next);    int i = 0, j = 0;    while (i < m)    {        while (j != -1 && p[j] != s[i])            j = next[j];        i++, j++;        if (j == n)        {            ok[i-1] = 1;            j = next[j];        }    }}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int T;    scanf("%d", &T);    for (int ncase = 1; ncase <= T; ncase++)    {        scanf("%s%s", a, b);        memset(ok, 0, sizeof(ok));        kmp(b, strlen(b), a, strlen(a));        memset(dp, 0, sizeof(dp));        dp[0] = ok[0];        int len = strlen(a);        int lenb = strlen(b);        for (int i = 1; i < len; i++)        {            dp[i] = dp[i-1];            if (ok[i]) dp[i] = (dp[i] + dp[i-lenb] + 1) % MOD;        }        printf("Case #%d: %d\n", ncase, dp[len-1] + 1);    }    return 0;}
0 0
原创粉丝点击