加密
【问题描述】
有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符。 相应的,不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符。给定原文s和加密后的字符串t,求t有多少子串可以通过解密得到原文s。
【输入格式】
输入第一行包含一个字符串t,第二行包含一个字符串s。
【输出格式】
输出一行,包含一个整数,代表可以通过解密得到原文的t的子串的数量。
【样例输入】
abcabcabc
cba
【样例输出】
9
【样例解释】
用[l,r]表示子串开头结尾的下标(从 0 开始编号) ,这 9 种方案是:[0,6],[0,7],[0,8],[1,6],[1,7],[1,8],[2,6],[2,7],[2,8]
【数据规模和约定】
对于30%的数据,|t| ≤1000。
对于100%的数据,1 ≤ |t| ≤ 300,000,1 ≤ |s| ≤ 200。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define ll long long #define N 300100 #define M 310 using namespace std; int n,m; ll ans(0); int f[M]={0},a[N]; char s[M],t[N]; int main() { freopen("encrypt.in","r",stdin); freopen("encrypt.out","w",stdout); scanf("%s%s",t+1,s+1); n=strlen(t+1); m=strlen(s+1); for (int i=1;i<=n;i++) { f[0]=i;//i前的数每减少一个数就能形成一个新序列 for (int j=m;j>=1;j--) if (t[i]==s[j]) f[j]=f[j-1]; //一个满足条件的序列时,与s[1]相等的数越靠后所能形成的序列个数更多。 //不断更新最大值。 ans+=f[m]; } printf("%I64d",ans); fclose(stdin); fclose(stdout); return 0; }
I'm so lost but not afraid ,I've been broken and raise again