zoukankan      html  css  js  c++  java
  • 加密

    !!!試題來自清北!!!

    【问题描述】
    有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符。 相应的,
    不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符。
    给定原文s和加密后的字符串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%的数据,|l| 1000。
    对于100%的数据,1 ≤ |l| ≤ 300,000,1 ≤ s ≤ 200。

    有一種不講道理的算法,方案數+=(l+1)*(r+1)。

    有一種更不講道理的去重方法,方案數-=(這次及前次中較小的l+1)*(這次及前次中較大的r+1)。

    這裡的[l,r]指最窄的滿足條件的區間(即該區間對應的t的子串中依次出現組成s的字符,且t[l]==s[0],t[r]==s[ls-1]。)(不要理解成只有一組區間)。

    代碼實現:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 using namespace std;
     5 long long lt,ls,jl[2],ans;//注意开long long。
     6 char t[3000000],s[300];
     7 bool p;
     8 void sf(long long x,long long y,long long z){
     9 if(y==ls){
    10 ans+=(z+1)*(lt-x+1);//無理的公式應用。
    11 if(jl[1]-jl[0]>=ls-1) ans-=(min(jl[0],z)+1)*(lt-max(jl[1],x-1));//無理的公式應用。
    12 jl[0]=z;jl[1]=x-1;//只需要存下上一組就夠了。
    13 return;
    14 }
    15 for(int i=x;i<lt;i++){
    16 if(t[i]==s[y]){
    17 if(y) {sf(i+1,y+1,z);break;}//break確保找的是最窄的合法區間。
    18 else sf(i+1,y+1,i);//i存左端點。
    19 }
    20 }
    21 }
    22 int main(){
    23 freopen("encrypt.in","r",stdin);
    24 freopen("encrypt.out","w",stdout);
    25 cin>>t>>s;
    26 lt=strlen(t);ls=strlen(s);
    27 sf(0,0,0);
    28 cout<<ans<<endl;
    29 return 0;
    30 }
    View Code

    有時候不要嘗試打開一些很大的輸入文件,數據流失會坑死你,我就調了一個多小時的AC代碼(當時沒過是數據範圍開小了,考試注意臨終檢查)。。。

  • 相关阅读:
    显而易见的python
    GitHub 使用教程图文详解
    linux下搭建hexo环境
    linux 删除软链接
    Django2.1入门教程
    windows下安装PyQt4
    python3 Flask安装
    学习之源
    白话C++系列教程
    面试笔试试题精选
  • 原文地址:https://www.cnblogs.com/J-william/p/6056787.html
Copyright © 2011-2022 走看看