NKOJ 密码 [暴力]

NKOJ 密码 [暴力]

问题描述

假发通过了不懈的努力,得到了将军家门锁的密码(一串小写英文字母)。但是假发被 十四和猩猩他们盯上了,所以假发需要把密码传递出去。因为假发不想十四他们发现几松门 前贴的小纸条就是将军家的密码,所以他加密了密码(新八:听起来有点诡异)。加密方法 如下:随机地,在密码中任意位置插入随机长度的小写字符串。 不过,假发相信银桑和他那么多年小学同学,一定能猜中密码是什么的(新八:银桑什 么时候成攮夷志士了!!!)。可是,写完了小纸条之后,假发觉得有点长,就想截去头和 尾各一段(可以为空),让剩下的中间那一段依然包含真~密码。想着想着,假发就想知道 有多少种可行方案。结果在沉迷于稿纸之际,假发被投进了狱门岛(新八:……)。于是, 就由你计算了。

输入格式

两行非空字符串,纯小写英文字母,第一行是加密后的密码,第二行是原密码。
第一行长度不超过 300000,第二行不超过 200。

输出格式

一行,有多少种方案。注意:不剪也是一种方案。

题解

好像没什么特别的算法…乘法原理??

i 为在新密码串中扫动的指针, j 为在原密码串(真密码)中扫动的指针。解题的关键就在于不停地扫动 i j 指针。固定原密码串,一位一位地在新密码串中匹配真密码。当匹配完一串真密码时,更新答案(注意是上一次匹配到的密码串的开头位置 L a s t P o s 与这一次的开头位置 C u r P o s 的差,即 A n s + = ( C u r P o s L a s t P o s ) ( n i + 1 ) 。不能不记录 L a s t P o s ,否则会造成重复计算),并把 i 移到 C u r P o s + 1 的位置<千万不要忘记T^T> j 移到原密码的第一位,然后重复以上操作。

注意细节(不剪也是一种方案)。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s1[300050],s2[250];
int main(){
    scanf("%s%s",s1+1,s2+1);
    int len1=strlen(s1+1),len2=strlen(s2+1);
    int i=1,j=1,Last,Cur=0;
    long long Ans=0;
    while(i<=len1){
        while(i<=len1 && s1[i]!=s2[j])i++;
        if(i>len1)break;
        if(j==1)Last=Cur,Cur=i;
        if(j==len2)Ans+=(long long)(Cur-Last)*(len1-i+1);
        i++,j++;
        if(j>len2)j=1,i=Cur+1;
    }
    printf("%lld",Ans);return 0;
}

猜你喜欢

转载自blog.csdn.net/ArliaStark/article/details/81256848