题目链接:
Another Meaning
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
As is known to all, in many cases, a word has two meanings. Such as “hehe”, which not only means “hehe”, but also means “excuse me”.
Today, ?? is chating with MeiZi online, MeiZi sends a sentence A to ??. ?? is so smart that he knows the word B in the sentence has two meanings. He wants to know how many kinds of meanings MeiZi can express.
Today, ?? is chating with MeiZi online, MeiZi sends a sentence A to ??. ?? is so smart that he knows the word B in the sentence has two meanings. He wants to know how many kinds of meanings MeiZi can express.
Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case contains two strings A and B, A means the sentence MeiZi sends to ??, B means the word B which has two menaings. string only contains lowercase letters.
Limits
T <= 30
|A| <= 100000
|B| <= |A|
Each test case contains two strings A and B, A means the sentence MeiZi sends to ??, B means the word B which has two menaings. string only contains lowercase letters.
Limits
T <= 30
|A| <= 100000
|B| <= |A|
Output
For each test case, output one line containing “Case #x: y” (without quotes) , where x is the test case number (starting from 1) and y is the number of the different meaning of this sentence may be. Since this number may be quite large, you should output the answer modulo 1000000007.
Sample Input
4
hehehe
hehe
woquxizaolehehe
woquxizaole
hehehehe
hehe
owoadiuhzgneninougur
iehiehieh
Sample Output
Case #1: 3
Case #2: 2
Case #3: 5
Case #4: 1
题意:
给了一个单词它有两种意思,现在有一个字符串.问你这个字符串有多少种不同的意思;
思路:
设dp[i]表示[1,i]这段字符串的意思总数,考虑以i位结尾的的这一小段是否和单词匹配;
如果匹配,dp[i]=dp[i-1]+dp[i-strlen(B)];不匹配的话dp[i]=dp[i-1];
然后就是kmp找出所有的匹配位置的结点flag[i]标记下来;
AC代码:
/************************************************
┆ ┏┓ ┏┓ ┆
┆┏┛┻━━━┛┻┓ ┆
┆┃ ┃ ┆
┆┃ ━ ┃ ┆
┆┃ ┳┛ ┗┳ ┃ ┆
┆┃ ┃ ┆
┆┃ ┻ ┃ ┆
┆┗━┓ ┏━┛ ┆
┆ ┃ ┃ ┆
┆ ┃ ┗━━━┓ ┆
┆ ┃ AC代马 ┣┓┆
┆ ┃ ┏┛┆
┆ ┗┓┓┏━┳┓┏┛ ┆
┆ ┃┫┫ ┃┫┫ ┆
┆ ┗┻┛ ┗┻┛ ┆
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
using namespace std;
#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
template<class T> void read(T&num) {
char CH; bool F=false;
for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
if(!p) { puts("0"); return; }
while(p) stk[++ tp] = p%10, p/=10;
while(tp) putchar(stk[tp--] + '0');
putchar('
');
}
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=1e5+100;
const int maxn=(1<<8);
const double eps=1e-8;
char A[N],B[N];
int nex[N],flag[N];
LL dp[N];
inline void makenext()
{
int k = -1,j = 0,len = strlen(B);
nex[0] = -1;
while(j < len)
{
if(k == -1||B[j] == B[k])
{
j++;
k++;
nex[j] = k;//相等的话就往后继续;
}
else k = nex[k];//不等的话就相当于kmp一样,把模式串的这个子串用已经求出来的next跳转;
}
}
inline void kmp()
{
mst(flag,0);
makenext();
int posP = 0,posT = 0;
int lenP = strlen(B),lenT = strlen(A);
while(posP < lenP&&posT < lenT)
{
if(posP == -1||B[posP] == A[posT])
{
posP++;
posT++;
}
else posP = nex[posP];
if(posP == lenP)
{
flag[posT-1]=1;
posP=nex[posP];
}
}
}
int main()
{
int t,Case=0;
read(t);
while(t--)
{
scanf("%s",A);
scanf("%s",B);
kmp();
int len=strlen(A),l=strlen(B);
dp[0]=1;
For(i,1,len)
{
if(!flag[i-1])dp[i]=dp[i-1];
else dp[i]=(dp[i-1]+dp[i-l])%mod;
}
printf("Case #%d: %lld
",++Case,dp[len]);
}
return 0;
}