未知:密碼——題解

密碼
題目描述
假髮通過了不懈的努力,得到了將軍家門鎖的密碼(一串小寫英文字母)。但是假髮被十四和猩猩他們盯上了,所以假髮需要把密碼傳遞出去。因爲假髮不想十四他們發現幾松門前貼的小紙條就是將軍家的密碼,所以他加密了密碼(新八:聽起來有點詭異)。加密方法如下:隨機地,在密碼中任意位置插入隨機長度的小寫字符串。
不過,假髮相信銀桑和他那麼多年小學同學,一定能猜中密碼是什麼的(新八:銀桑什麼時候成攮夷志士了!!!)。可是,寫完了小紙條之後,假髮覺得有點長,就想截去頭和尾各一段(可以爲空),讓剩下的中間那一段依然包含真~密碼。想着想着,假髮就想知道有多少種可行方案。結果在沉迷於稿紙之際,假髮被投進了獄門島(新八:……)。於是,就由你計算了。
輸入
兩行非空字符串,純小寫英文字母,第一行是加密後的密碼,第二行是原密碼。
第一行長度不超過300000,第二行不超過200。
輸出
一行,有多少種方案。注意:不剪也是一種方案。
樣例輸入
abcabcabc
cba
樣例輸出
9
提示
樣例解釋
用(L,R)表示一種方案,其中L和R分別表示截去頭和尾的長度。這9鍾方案分別是(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)。
數據說明
30%的數據滿足第一行長度不超過1000。

這題正解竟然喫檸檬的是暴力!!!!!!!!!!11111111

不過純暴力只能過30%

那麼正解的暴力就是。
我們記錄密碼的第一位字母所在原串的位置。
然後在掃描過程中每匹配成功一次,就傳導第一位字母所在原串的位置。
並且只要掃描一次就加上最後一位字母所在的位置。
//如果還沒有掃到最後一位字母的話就是+0(顯然的)
原理:
當成功掃到了密碼之後,密碼以後的字符(個數爲n-1)和密碼以前的字符(個數爲m-1)就都是“可刪狀態”,那麼對於密碼以後的字符的每一個字符(或者不刪)都有m種刪法,那麼就共有m*n個刪法。
所以正解正是將乘法變成了加法做。

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
char s[310001];
char s0[231];
long long ans=0;
int f[31001]={0};
int main(){
    gets(s+1);
    gets(s0+1);
    int len1=strlen(s+1);
    int len2=strlen(s0+1);
    for(int i=1;i<=len1;i++){
        f[0]=i;
        for(int j=len2;j>=1;j--){
            if(s0[j]==s[i]){
                f[j]=f[j-1];
            }
        }
        ans+=f[len2];
    }
    printf("%lld",ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章