Odd Palindromes Two Pointers

来源:互联网 发布:平板软件市场 编辑:程序博客网 时间:2024/06/16 16:01

题目大意

如果一个字符串所有奇数长度的连续字符串都是回文串, 我们叫它odd palindromic
给你一个长度长度为n的字符串S, 你最多可以改变k个字符, 求能得到的最长odd palindromic连续子串长度是多少

思路

odd palindromic字符串所有奇数长度子串都为回文串, 所以所有长度为3的子串都是回文串, 所以有S[i] == S[i+2], 即所有奇数位置字符相同, 所有偶数位置字符相同
我们利用尺取法, 对于每个区间[l, r], 我们用一个cnt[2][26]来统计奇数偶数位置各个字母出现的频率, 如果区间内奇数出现频率最高的字符的出现次数, 加上偶数最高频率字符出现次数+k(可以改变的字符个数)小于区间长度r-l+1, 那么这个区间不能构造成odd palindromic, ++l, 更新cnt, 一直到能够构造成一个odd palindromic或者l==r(此时长度为一, 一定是odd palindromic), 用这个区间长度更新答案, 然后r++, 更新cnt
r++之后, l可以保持原来的位置不变, 因为r++最多让最高频率字符出现次数+1, 而区间长度也增加了一, 所以,以新的r为结尾的odd palindromic最左也只可能到l

代码

Score: 100/100 (171 ms - 1340 KB)

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 1E6 + 100;char s[MAXN];int cnt[2][26], k;int main(){    scanf("%d%s", &k, s);    int left = 0, len = strlen(s), mx = 0;    auto GetMaxSum = []()    {        int s = 0;        for(int i=0; i<2; ++i)        {            int mx = 0;            for(int j=0; j<26; ++j) mx = max(mx, cnt[i][j]);            s += mx;        }        return s;    };    for(int i=0; i<len; ++i)    {        ++cnt[i&1][s[i]-'a'];        while(k + GetMaxSum() < i-left+1) --cnt[left&1][s[left]-'a'], ++left;        mx = max(mx, i-left+1);    }    printf("%d\n", mx);    return 0;}
原创粉丝点击