AtCoder Contest 229-D-Longest X

Problem Statement

Given is a string SS consisting of X and ..

You can do the following operation on SS between 00 and KK times (inclusive).

  • Replace a . with an X.

What is the maximum possible number of consecutive Xs in SS after the operations?

Constraints

  • 1 \leq |S| \leq 2 \times 10^51≤∣S∣≤2×105
  • Each character of SS is X or ..
  • 0 \leq K \leq 2 \times 10^50≤K≤2×105
  • KK is an integer.

Input

Input is given from Standard Input in the following format:

SS
KK

Output

Print the answer.


Sample Input 1 Copy

Copy

XX...X.X.X.
2

Sample Output 1 Copy

Copy

5

After replacing the Xs at the 77-th and 99-th positions with X, we have XX...XXXXX., which has five consecutive Xs at 66-th through 1010-th positions.
We cannot have six or more consecutive Xs, so the answer is 55.


Sample Input 2 Copy

Copy

XXXX
200000

Sample Output 2 Copy

Copy

4

It is allowed to do zero operations.

题目类型:单调队列;

解题目标:找到可能在k次内被补齐的最长序列长度

解题思路:

                第一种:(思路简单,耗费空间)

                1)用vector记录每个‘.’的下标;

                2)遍历vector数组,比较下标相隔k的两个元素的之间差的最大值。

                (左边界和右边界也要加入, 0, len+1, 因为最长的序列可能在两端)

                第二种:(单调队列)

                1)读入string,

                2)遍历,遇到‘.’,计数, 当计到k时,比较当前右界与左界(左界所在的点是‘.’)的差,留取最大的;模拟了宽度为K的窗口滑动问题。

AC代码:

1)

    #include  <bits/stdc++.h>
    #define rep(x, a, b) for(int x=a; x<=b; x++)
    #define inf 0x3f3f3f3f
    #define ll long long
    using namespace std;
    const int N= 3e5+10;


    int main()
    {
        string s;
        int k, cot = 0;
        cin>>s>>k;
        vector<int> v;
        v.push_back(0);
        int len = (int)s.length();
        for(int i = 0; i<=len-1; i++)
            if(s[i] == '.')
                v.push_back(i+1);
        v.push_back(len+1);
        int len2 = (int)v.size();
        int ans = 0;

       if(k > len2-2)
        {
            cout<<len<<endl;
            return 0;
        }
        else {

            for(int i = 0; i<= len2-2-k ; i++)
            {
                //cout<<v[i+k+1]<<' '<<v[i]<<endl;
                ans = max(v[i+k+1] - v[i], ans);
            }
            ans--;
            cout<<ans<<endl;
        }

        return 0;
    }

2)(更优)

#include  <bits/stdc++.h>
#define rep(x, a, b) for(int x=a; x<=b; x++)
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
const int N= 3e5+10;


int main()
{
    string s;
    int k, cot = 0;
    cin>>s>>k;
    int ans  = 0;
    vector<int> v;
    int d =0, l =0 ,r=0;
    int len = (int)s.length();
    for(int i =0; i<=len-1; i++)
    {
        if(s[i] == '.') d++;
        if(d > k)
        {
            if(s[l] == '.')
                d--;
            l++;
        }

        ans = max(ans, i -l +1);
    }
    cout<<ans;
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值