zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 17 C 二分

    题目链接:http://codeforces.com/contest/762/problem/C

    题意:两个字符串 s1 s2 长度1e5 ,问题 串2 去掉一个最短连续子串,使得剩下的串拼起来是 串1 的一个子串。

    思路:预处理s2从头匹配最远延伸以及从尾匹配的最远延伸,之后利用这两个数组,可以通过二分答案o(n)判断解决问题

    备注:寒假摸鱼。。

    代码: 

    #include<bits/stdc++.h>
    #define bug(x) cout<<"bug "<<x<<endl;
    using namespace std;
    #define ll long long
    const int maxn=1e6+10;
    string s1,s2;
    int a[maxn],b[maxn];
    
    void init(){
        memset(a,-1,sizeof(a));
        memset(b,-1,sizeof(b));
        int idx=-1;
        for(int i=0;i<s2.size();i++){
            idx++;
            while(s2[i]!=s1[idx]&&idx<s1.size()){
                idx++;
            }
            if(idx>=s1.size()) break;
            a[i]=idx;
        }
        idx=s1.size();
        for(int i=s2.size()-1;i>=0;i--){
            idx--;
            while(s2[i]!=s1[idx]&&idx>=0){
                idx--;
            }
            if(idx<0) break;
            b[i]=idx;
        }
    }
    
    int ok(int x){
        if(b[x]!=-1) return 0;
        if(a[s2.size()-x-1]!=-1) return s2.size()-x;
        for(int i=1;i+x<s2.size();i++){
            if(a[i-1]!=-1&&b[i+x]!=-1&&a[i-1]<b[i+x])
                return i;
        }
        return -1;
    }
    
    int main(){
        cin>>s1>>s2;
        init();
        int ans=0;
        int lo=0,hi=s2.size();
        while(lo<=hi){
            int mid=(lo+hi)/2;
            if(ok(mid)!=-1) hi=mid-1;
            else lo=mid+1;
        }
        if(lo>=s2.size()) puts("-");
        else{
            int x=ok(lo);
            for(int i=0;i<x;i++) cout<<s2[i];
            for(int i=x+lo;i<s2.size();i++) cout<<s2[i];
            puts("");
        }
        return 0;
    }
    



  • 相关阅读:
    单例模式
    设计模式
    C#判断Textbox是否为数字
    C#判断输入的是否是汉字
    C#如何测试代码运行时间
    网上 server2008数据库恢复方法
    C# 控件的缩写
    SQLite主键自增代码
    Sqlite数据库联合查询及表复制等详述
    C#中超链接方法
  • 原文地址:https://www.cnblogs.com/zhangxianlong/p/10672519.html
Copyright © 2011-2022 走看看