zoukankan      html  css  js  c++  java
  • 回文检测题解


    题目右转luogu1210

    我看到这道题的第一想法是枚举答案 (长度)

    但是很显然会超时,怎样优化枚举是关键

    我想到了二分答案。但是二分答案要求答案具有单调性。

    乍一看,似乎回文子串没什么单调性。但是如果我们将答案分为奇偶两种,答案的单调性就出来了

    1.当最长回文串长度是奇数时:

    不妨假设长度为(9),那么我们就会发现,(9)以下的奇数长度 (1,3,5,7) 都是存在回文串的,奇数的单调性我们找到了

    2.当回文串为偶数时
    同理,设长度为(6)(6)以下的偶数长度 (2,4) 也都是可以的。

    然后我们就可以开始二分了

    相信写程序对各位DALAO不是问题,上代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=20005;
    string s,t;int len1;
    int begin,end;
    int ans;
    struct node
    {
        char S;
        int start;
    }st[maxn];
    bool ok(int x,int y)
    {
        int rt=x,lt=y;
        while(rt<=lt)
        {
            if(st[rt].S!=st[lt].S) return false;
            rt++,lt--; 
        }
        return true;
    }
    bool add(int x)
    {
        int head=1,tail=x;
        while(tail<=len1)
        {
            if(ok(head,tail))
            {
               begin=st[head].start;
               end=st[tail].start;
               return true;
            }
            head++,tail++;
        }
        return false;
    }
    int main()
    {
        while(getline(cin,t))//注意读入数据的处理 
        {
            s+=t+'
    ';
        };
        s=' '+s;
        int len=s.size()-1;
        for(int i=1;i<=len;i++)
        {
            if(s[i]>='A'&&s[i]<='Z') st[++len1].S=s[i]-'A'+'a',st[len1].start=i;//改小写 
            else if(s[i]>='a'&&s[i]<='z') st[++len1].S=s[i],st[len1].start=i; 
        }
        int lt=0,rt;
        if(len1%2==0) rt=len1;
        else rt=len1+1;
        while(lt+2<rt)//二分奇数  特别注意 lt+2 
        {
            int mid=(lt+rt)/2;
            if(mid%2==0) mid++;
            if(add(mid)) lt=mid;
            else rt=mid;
        }
        int b=begin,e=end;
        ans=lt;
        lt=1;
        if(len1%2==0) rt=len1+1;
        else rt=len1;
        while(lt+2<rt)//二分偶数  
        {
            int mid=(lt+rt)/2;
            if(mid%2==1) mid++;
            if(add(mid)) lt=mid;
            else rt=mid;
        }
        if(ans>lt)//比较大小 
        {
            cout<<ans<<endl;
            for(int i=b;i<=e;i++)
               cout<<s[i];
        }
        else 
        {
            cout<<lt<<endl;
            for(int i=begin;i<=end;i++)
               cout<<s[i];
        }
        return 0;
    }
    
  • 相关阅读:
    siamese跟踪论文思考
    卷积与相关
    pytorch保存模型等相关参数,利用torch.save(),以及读取保存之后的文件
    发表在 Science 上的一种新聚类算法
    word2vec 中的数学原理详解
    一种并行随机梯度下降法
    一种利用 Cumulative Penalty 训练 L1 正则 Log-linear 模型的随机梯度下降法
    最大熵学习笔记(六)优缺点分析
    最大熵学习笔记(四)模型求解
    最大熵学习笔记(三)最大熵模型
  • 原文地址:https://www.cnblogs.com/GDOI2018/p/10219582.html
Copyright © 2011-2022 走看看