zoukankan      html  css  js  c++  java
  • 加密(模拟)

    【问题描述】


    有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符。 相应的,
    不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符。
    给定原文?和加密后的字符串?,求?有多少子串可以通过解密得到原文?。


    【输入格式】


    输入第一行包含一个字符串?,第二行包含一个字符串?。


    【输出格式】


    输出一行,包含一个整数,代表可以通过解密得到原文的?的子串的数量。


    【样例输入】


    abcabcabc
    cba


    【样例输出】


    9


    【样例解释】


    用[?,?]表示子串开头结尾的下标(从 0 开始编号) ,这 9 种方案是:
    [0,6],[0,7],[0,8],[1,6],[1,7],[1,8],[2,6],[2,7],[2,8]


    【数据规模和约定】


    30%的数据,|?| 1000。
    对于100%的数据,1 ≤ |?| ≤ 300,000,1 ≤ ? ≤ 200。

    思路:

      暴力出奇迹,搜索压正解

      题目的要求是求出t中所有能成为s的子串

      可以换一种说法

      我们要找的就是t的包含有s串的元素的子串

      但是这个子串只是包含s串还不行

      需要包含的s串的元素有顺序

      就是说从t[0]到t[length_t-1]中

      只要是t[now]和s[0]相等就开始向后面找是否以t[now]开头的子串包含s串的所有元素

      如果找到了

      则标记以t[now]开头的子串的末尾元素记为t[end]

      然后计算t[now]以前的元素个数和t[end]以后的元素个数

      这两个个数的值相乘就是t[now]到t[end]这个子串能够延伸的子串个数(包括它自己)

      O(lenth_t)循环一遍找到所有的t[now]==s[0]的now值

      每个now值都找所有的s串在t串中的顺序值

      如果某个now值没有找全s串的值则返回

      所有能得出值得now的和

      还不是最终的答案

      我们会发现这样所有的now值得出的子串个数会有重复

      这时需要用容斥原理来减去重复的部分

      这样就能得出最后的答案

      但是

      还没完

      虽然答案对了

      但是时间复杂度依然高

      会超时

      所以我们需要做一下优化

      就是弄一个数组来储存所有上一个now的s串元素在t串中的位置

      如果现在的now的位置<s[1]的位置

      则无需再次寻找当前now的s串的元素在t串中位置

      我们可以把上一个now的s串的元素的位置引过来用

      这样减少寻找now的次数

      时间会得到很大的优化

      在时间很少的情况下得出答案;

    来,上代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    
    using namespace std;
    
    int len_t,len_s,now_s,be_t=-1,s_where[202];
    
    char t_problem[300005],s_before[202];
    
    unsigned long long int ans=0;
    
    bool ok_all=false;
    
    void work_for_ans(int now_t)
    {
        if(now_t<s_where[1])
        {
            ans+=(now_t-be_t)*(len_t-s_where[len_s-1]);
            be_t=now_t;
        }
        else
        {
            now_s=1;
            for(int i=now_t+1;i<=len_t;i++)
            {
                if(i==len_t)
                {
                    ok_all=true;
                    break;
                }
                if(t_problem[i]==s_before[now_s])
                {
                    s_where[now_s]=i;
                    now_s++;
                }
                if(now_s==len_s) break;
            }
            if(!ok_all)
            {
                ans+=(now_t-be_t)*(len_t-s_where[len_s-1]);
                be_t=now_t;
            }
        }
    }
    
    int main()
    {
        scanf("%s",t_problem);
        scanf("%s",s_before);
        len_t=strlen(t_problem),len_s=strlen(s_before);
        if(len_s==1)
        {
            for(int i=0 ; i<len_t ;i++)
            {
                if(t_problem[i]==s_before[0])
                {
                    ans+=(i-be_t)*(len_t-i);
                    be_t=i;
                }
            }
            cout<<ans<<endl;
            return 0;
        }
        for(int i=0 ; i<len_t ; i++)
        {
            if(t_problem[i]==s_before[0]) work_for_ans(i);
            if(ok_all) break;
        }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    撸羊毛的一些心得体会
    GET和POST的区别
    接口测试基础
    Charles老版本教程
    【2019】Charles视频教程,接口测试工具最新教程
    关于Synchronized研伸扩展
    Java多线程之线程的协作
    十七.jmeter分布式测试
    十六.jmeter链接mysql测试
    十五.jmeter FTP服务器连接
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6056611.html
Copyright © 2011-2022 走看看