首页 > 其他分享 >01反转

01反转

时间:2023-08-23 10:58:47浏览次数:22  
标签:01 int 反转 个数 枚举 maxn 连续

题目描述

有一个长为 的字符串 ,只含 0和 1 。你可以进行最多\(K\)次如下操作( 0 次也可以):

选择字符串 \(S\)的一个子串,将其中的字符反转( 0变成1 ,1变成0 )。

进行不超过\(K\)次操作后,求最长的连续的 1的长度。

数据约定

对于100%的数据:字符串只由0和1组成,长度为\(1 \leq n、k \leq 10^5\) 。

思路分析:

对于这道题而言,首先我想要发现DP,但是发现n和k都非常大,没有办法DP

继续思考,发现反转1没有任何用处,若反转的区间中有,则会将变成导致连续的区间 1 断开,所以最优情况下,反转操作只会反转连续的0,确定了这个之后,这就好写了

后来我想把连续的0的个数处理出来,找到最大的K个即可,后来发现这样的想法是错误的,因为他是连续的1的个数,有可能第一多的旁边跟着的0的个数比较小,同时连续0的个数同时相关着连续1的个数,所以不能贪心,只能枚举。

我们把题目中的连续的0合并,同时因为n非常大,我们也需要把题目中连续的1合并,对于每个0而言,处理出三个部分:

\(cnt[i] 第i个位置上共有多少个连续的0\)

\(L[i] 第i个位置上前面有多少个连续的1\)

\(R[i] 第i歌位置上后面有多少个连续的1\)

有了这个之后,我们枚举0即可,找到连续k个,但是我如果我枚举的话,就会T

最后我使用队列,这K个0肯定是连续的,枚举会造成时间的浪费,使用队列,满足k个,计算答案,同时把第一个踢出去,继续加入即可。

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
int n, k;
char s[maxn];
int l[maxn], r[maxn], cnt[maxn], xx[maxn], ans, ss[maxn];
queue<int> q;
int main() {
    scanf("%d%d", &n, &k);
    ;
    scanf("%s", s + 1);
    bool flag = true;
    for (int i = 1; i <= n; i++) {
        if (s[i] == '1') {
            flag = false;
            break;
        }
    }
    if (flag == true) {
        cout << n;
        return 0;
    }
    flag = true;
    for (int i = 1; i <= n; i++) {
        if (s[i] == '0') {
            flag = false;
            break;
        }
    }
    if (flag == true) {
        cout << n;
        return 0;
    }
    int j = 1;
    for (int i = 1; i <= n; i++) {
        xx[j] = s[i] - '0';
        if (xx[j] == 1) {
            j++;
            continue;
        }
        while (s[i] == '0') {
            cnt[j]++;
            i++;
        }
        i--;
        j++;
    }
    int sum = 0;
    for (int i = 1; i <= j - 1; i++) {
        if (xx[i] == 1)
            sum++;
        if (xx[i] == 0) {
            l[i] = sum;
            sum = 0;
        }
    }
    int pos;
    for (int i = 1; i <= j - 1; i++) {
        if (xx[i] == 1)
            continue;
        if (xx[i] == 0)
            pos = i;
        i++;
        while (xx[i] == 1) {
            i++;
        }
        if (i <= j - 1) {
            r[pos] = l[i];
            i--;
        } else
            r[pos] = j - pos - 1;
    }
    n = 0;
    for (int i = 1; i <= j - 1; i++) {
        if (xx[i] == 0) {
            n++;
            ss[n] = 0;
            int x = cnt[i];
            cnt[n] = x;
            x = l[i];
            l[n] = x;
            x = r[i];
            r[n] = x;
        }
    }
    sum = 0;
    for (int i = 1; i <= n; i++) {
        if (q.size() < k) {
            q.push(i);
            sum += l[i] + cnt[i];
        }
        if (q.size() == k) {
            sum += r[i];
            ans = max(ans, sum);
            int pos = q.front();
            q.pop();
            sum -= r[i];
            sum = sum - l[pos] - cnt[pos];
        }
        if (q.size() < k && i == n) {
            sum += r[i];
            ans = max(ans, sum);
        }
    }
    printf("%d", ans);
    return 0;
}
/**
14 8
11101010110011
 */

标签:01,int,反转,个数,枚举,maxn,连续
From: https://www.cnblogs.com/sdfzls/p/17650550.html

相关文章

  • AOJ0121(Seven Puzzle, BFS+Cantor+逆向思维)
    参考康托展开自己真的一点头绪都没有,根据前面的大神博客自己几乎100%复制了一个,但是还是WA,觉得还是出在选方向时的判断上面。Cantor感觉这个可以作为模板,状态压缩的一个思路。还有就是BFS特点:1.从一个起点到一个终点2.起点和终点可以互相到达,双向的//#defineLOCAL#include......
  • poj 1001 a+b
    #include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>#include<iostream>usingnamespacestd;intmain(){inta,b;while(scanf("%d%d",&a,&b)!=EOF)printf("%d......
  • Python基础入门学习笔记 015字符串:格式化
     字符串格式化符号含义 将ASCII码97对应的字符输出 格式化整数 格式化操作符辅助命令5表示输出为五位数Python的转义字符及其含义......
  • Python基础入门学习笔记 016 序列!序列!
    •列表、元组和字符串的共同点–都可以通过索引得到每一个元素–默认索引值总是从0开始–可以通过分片的方法得到一个范围内的元素的集合–有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)使用list方法 元组转换为列表 max()返回序列或者参数集合中的最大......
  • Python基础入门学习笔记 018 函数:灵活即强大
    形参和实参>>>defMyFirstFunction(name):'函数定义过程中的name是叫形参'#因为Ta只是一个形式,表示占据一个参数位置print('传递进来的'+name+'叫做实参,因为Ta是具体的参数值!')>>>MyFirstFunction('小甲鱼')传递进来的小甲鱼叫做实参,因为Ta是具体的参数值!关键字参数......
  • Python基础入门学习笔记 011列表:一个打了激素的数组2
    从列表中获取元素•跟数组一样,我们可以通过元素的索引值(index)从列表获取单个元素,注意,列表索引值是从 0 开始的。 从列表删除元素 remove()函数表示从列表中删除某个元素 del()函数也表示从列表中删除某个元素 pop()函数从列表中取出最后一个元素列表分片(Slice)•......
  • Python基础入门学习笔记 012列表:一个打了激素的数组3
    列表的一些常用操作符•比较操作符 •逻辑操作符 •连接操作符 •重复操作符 •成员关系操作符 关于分片“拷贝”概念的补充 >>>dir(list)可查看所有列表的操作函数 count()函数可计算列表中相同元素个数 index()函数可索引列表元素 reverse()将列......
  • [CEOI2011] Matching 题解
    [CEOI2011]Matching题解题外话:看了其他人题解后作为初学$kmp$的我非常蒙,因为对这个算法的核心掌握不太好,不知道怎么维护动态的序列,因此写下此题解共享经验,建议只会打模板的看看。参考资料:https://www.cnblogs.com/fusiwei/p/11944975.html思路引导:看到数据范围,又和真实......
  • Python基础入门学习笔记 001 我和Python的第一次亲密接触
    从IDLE启动Python•IDLE是一个PythonShell,shell的意思就是“外壳”,基本上来说,就是一个通过键入文本与程序交互的途径!•我们看到>>>这个提示符,Ta的含义是告诉你,Python已经准备好了,在等着你键入Python指令呢。•好了,大家试试在IDLE里输入:>>>print(“Ilovefishc.com”) ......
  • 自我介绍:20231301 周子昂
    自我介绍大家好!我叫周子昂,来自北京。(0)照片(1)形容词周:思绪“周”密,严谨踏实做事之前喜欢整体思考,有一定的布局。尽可能在做事时脚踏实地,认真仔细。事后反思总结经验教训,以便下次更好。子:谦谦君“子”,温和有礼待人接物有基本的礼仪与尊重。在有能力的范围内尽可能地帮助......