【备战秋招】每日一题:4月23日美团春招第四题:题面+题目思路 + C++/python/js/Go/java带注释

news2024/11/16 12:24:26

 为了更好的阅读体检,为了更好的阅读体检,,可以查看我的算法学习博客第四题-01串的代价

在线评测链接:P1248

题目内容

塔子哥是一个喜欢研究密码的人,他经常在网上寻找各种有趣的密码挑战。他最近发现了一个神秘的网站,网站上只有一个输入框和一个提交按钮,没有任何提示。塔子哥好奇地输入了一些内容,发现网站会返回一个长度为 n 的 01 串,只包含字符 01 的串。塔子哥觉得这个串一定是一个密码的线索,他想要破解它。

塔子哥仔细观察了这个串,发现它里面隐藏着一些规律,比如有些位置的字符总是相同的,有些位置的字符总是相反的。塔子哥猜测这些规律可能是密码的组成部分,他想要把它们都保留下来,并且删除掉无关的字符。但是,塔子哥不想删除太多的字符,也不想保留太长的串。所以,他想知道,在保证删除一个前缀和一个后缀的情况下(前缀和后缀都可以为空),即保留一个原串的连续子串(可以为空),他需要最小化以下代价:

  1. 被删除的字符 1 的个数;

  2. 剩下的子串的字符 0 的个数。

塔子哥会给你总共若干次询问,每次询问他会告诉你网站返回给他的 01 串。你需要帮助塔子哥判断,在每次询问中,他需要输出的最小代价是多少。

输入描述

一个长度为n(1 \leq n \leq 1e5)的 01 字符串。

输出描述

一个整数,表示最小的操作代价。

样例1

输入

101110110

输出

2

样例解释

删除前两个字符和最后一个字符,代价为 1 ;

保留下来的字符中有一个 0 ,代价为 1 ,故代价之和为 2 。

样例2

输入

1010110001

输出

3

思路

思维 + 贪心

由于可以删除一个前缀和一个后缀,故可以这么考虑: 枚举分界点 i,[1,i] 中删除一个前缀,[i+1,n] 中删除一个后缀。取两部分代价之和的最小值。

具体删除的步骤:

  • 如果遇到一个 1 ,则不删除,记录下来。

  • 如果遇到一个 0 ,对于删除到这个 0 的代价,和保留这个 0 的代价,两者取 min ,对于保留这个 0 的代价,就是 +1 ,对于删除到这个 0 的代价,就是将目前所有存储的 1 都删除。

时间复杂度:O(n)

类似题目推荐

LeetCode

LeetCode上的贪心题,代码随想录总结的非常好了,见 贪心 - 代码随想录

Codefun2000

  1. P1091. 米哈游 2023.03.19-第一题-交换字符

  2. P1235. 百度 2023.04.15-实习-第一题-字符串前缀

  3. P1005. 腾讯 2022.10.16-汽车

  4. P1137 美团 2023.04.01-第一题-整理

  5. P1077 美团 2023.3.11-第一题-字符串修改

  6. P1024 百度 2022.9.13-01反转

  7. P1089 美团 2023.3.18.10点-第三题-塔子哥的回文串

代码

CPP

#include <bits/stdc++.h>
using namespace std;
​
int main()
{
    string s;
    cin >> s;
​
    int n = s.size();
​
    vector<int> suf(n + 1);
    suf[n] = 0;
​
    int one = 0, val = 0;
    // 预处理出 suf[i] ,suf[i] 表示 [i, n - 1] 这个串删除后缀后的最小代价
    for (int i = n - 1; i >= 0; --i) {
        // 如果是 0
        if (s[i] == '0') {
            if (one > 0) {
                // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
                // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
                one -= 1;
                val += 1;
            } 
​
            // else {
            //     如果不存在 1,这个 0 可以直接删
            // } 
        } else {
            // 如果遇到的是 1,则先不删除,保留下来,和之后遇到的 0 相抵
            one += 1;
        }
        suf[i] = val;
    }
​
    one = val = 0;
    int ans = suf[0];
    // 枚举 i 为分界点
    // 1. 在 [0, i] 这个串删除前缀的最小值,动态维护
    // 2. 在 [i+1, n-1] 这个串删除后缀的最小值suf[i+1],已经预处理
    for (int i = 0; i < n; ++i) {
        if (s[i] == '0') {
            // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
            // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
            if (one > 0) {
                one -= 1;
                val += 1;
            }
        } else {
            one += 1;
        }
        ans = min(ans, suf[i + 1] + val);
    }
​
    cout << ans << "\n";
​
    return 0;
}

python

s = input()
​
n = len(s)
​
suf = [0] * (n + 1)
​
one, val = 0, 0
# 预处理出 suf[i] ,suf[i] 表示 [i, n - 1] 这个串删除后缀后的最小代价
for i in range(n - 1, -1, -1):
    # 如果是 0
    if s[i] == '0':
        if one > 0:
            # 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
            # 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
            one -= 1
            val += 1
        # else:
        #     如果不存在 1,这个 0 可以直接删
    else:
        # 如果遇到的是 1,则先不删除,保留下来,和之后遇到的 0 相抵
        one += 1
    suf[i] = val
​
one, val = 0, 0
ans = suf[0]
# 枚举 i 为分界点
# 1. 在 [0, i] 这个串删除前缀的最小值,动态维护
# 2. 在 [i+1, n-1] 这个串删除后缀的最小值suf[i+1],已经预处理
for i in range(n):
    if s[i] == '0':
        # 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
        # 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
        if one > 0:
            one -= 1
            val += 1
    else:
        one += 1
    ans = min(ans, suf[i + 1] + val)
​
print(ans)

Java

import java.util.Scanner;
​
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        int n = s.length();
​
        int[] suf = new int[n + 1];
        suf[n] = 0;
        int one = 0, val = 0;
​
        // 预处理出 suf[i] ,suf[i] 表示 [i, n - 1] 这个串删除后缀后的最小代价
        for (int i = n - 1; i >= 0; --i) {
            // 如果是 0
            if (s.charAt(i) == '0') {
                if (one > 0) {
                    // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
                    // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
                    one -= 1;
                    val += 1;
                }
                // else {
                //     如果不存在 1,这个 0 可以直接删
                // } 
            } else {
                // 如果遇到的是 1,则先不删除,保留下来,和之后遇到的 0 相抵
                one += 1;
            }
            suf[i] = val;
        }
​
        one = val = 0;
        int ans = suf[0];
​
        // 枚举 i 为分界点
        // 1. 在 [0, i] 这个串删除前缀的最小值,动态维护
        // 2. 在 [i+1, n-1] 这个串删除后缀的最小值suf[i+1],已经预处理
        for (int i = 0; i < n; ++i) {
            if (s.charAt(i) == '0') {
                // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
                // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
                if (one > 0) {
                    one -= 1;
                    val += 1;
                }
            } else {
                one += 1;
            }
            ans = Math.min(ans, suf[i + 1] + val);
        }
​
        System.out.println(ans);
    }
}

Go

package main
​
import "fmt"
​
func main() {
    var s string
    fmt.Scanln(&s)
​
    n := len(s)
    suf := make([]int, n+1)
​
    suf[n] = 0
    one := 0
    val := 0
    // 预处理出 suf[i] ,suf[i] 表示 [i, n - 1] 这个串删除后缀后的最小代价
    for i := n - 1; i >= 0; i-- {
        if s[i] == '0' {
            // 如果是 0
            if one > 0 {
                // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
                // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
                one -= 1
                val += 1
            }
​
            // else {
            //     如果不存在 1,这个 0 可以直接删
            // } 
        } else {
            // 如果遇到的是 1,则先不删除,保留下来,和之后遇到的 0 相抵
            one += 1
        }
        suf[i] = val
    }
​
    one = 0
    val = 0
    ans := suf[0]
​
    // 枚举 i 为分界点
    // 1. 在 [0, i] 这个串删除前缀的最小值,动态维护
    // 2. 在 [i+1, n-1] 这个串删除后缀的最小值suf[i+1],已经预处理
    for i := 0; i < n; i++ {
        if s[i] == '0' {
            // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
            // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
            if one > 0 {
                one -= 1
                val += 1
            }
        } else {
            one += 1
        }
​
        ans = min(ans, val+suf[i+1])
    }
​
    fmt.Println(ans)
}
​
func min(x, y int) int {
    if x < y {
        return x
    }
    return y
}
​

Js

process.stdin.resume();
process.stdin.setEncoding('utf-8');
let input = '';
process.stdin.on('data', (data) => {
    input += data;
    return;
});
process.stdin.on('end', () => {
    const s = input.trim();
​
    const n = s.length;
​
    const suf = new Array(n + 1);
    suf[n] = 0;
​
    let one = 0, val = 0;
    // 预处理出 suf[i] ,suf[i] 表示 [i, n - 1] 这个串删除后缀后的最小代价
    for (let i = n - 1; i >= 0; --i) {
        // 如果是 0
        if (s[i] === '0') {
            if (one > 0) {
                // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
                // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
                one -= 1;
                val += 1;
            } 
​
            // else {
            //     如果不存在 1,这个 0 可以直接删
            // } 
        } else {
            // 如果遇到的是 1,则先不删除,保留下来,和之后遇到的 0 相抵
            one += 1;
        }
        suf[i] = val;
    }
​
    one = val = 0;
    let ans = suf[0];
    // 枚举 i 为分界点
    // 1. 在 [0, i] 这个串删除前缀的最小值,动态维护
    // 2. 在 [i+1, n-1] 这个串删除后缀的最小值suf[i+1],已经预处理
    for (let i = 0; i < n; ++i) {
        if (s[i] === '0') {
            // 如果存在 1,就要保留这个 0 了,但是要维护一个 one 的数量,
            // 如果 one 的数量为 0 后,下次遇到 0 就不如将他们都删了。
            if (one > 0) {
                one -= 1;
                val += 1;
            }
        } else {
            one += 1;
        }
        ans = Math.min(ans, suf[i + 1] + val);
    }
​
    console.log(ans);
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/655500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指定字符串数组中每个元素sn的长度L如果sn长度比L短,则补充空格,且sn居中如果sn长度比L长,则保留sn左侧L个字符

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定字符串数组中每个元素sn的长度L 如果sn长度比L短&#xff0c;则补充空格,且sn居中 如果sn长度比L长&#xff0c;则保留sn左侧L个字符 [太阳]选择题 下列代码最后输出的结果是&#xff1f…

基于Java在线购物系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

MindFusion.Java Swing Pack 2023.R1 Crack

MindFusion.Java Swing Pack 2023.R1 改进了图表、电子表格和虚拟键盘。 6月 15&#xff0c; 2023 - 16&#xff1a;06 新版本 特征 MindFusion.Diagramming 的新功能 空间索引 - 创建项目位置索引&#xff0c;以便更快地进行命中测试和视口裁剪查询。这极大地提高了包含数…

ch8_1_CPU的结构和功能

1. cpu的结构 1.1CPU 的功能 控制器的功能 控制器的功能具体作用取指令指令控制分析指令操作控制执行指令&#xff0c; 发出各种操作命令控制程序输入与结果的输出时间控制总线管理处理中断处理异常情况和特殊请求数据加工 运算器的功能 实现算术运算 和 逻辑运算&#x…

基于Java多角色学生管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

基于Java网上服装销售系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

【大数据】可视化仪表板 - Superset的安装和使用

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

11-高性能JSON库——fastjson2

目录 1.具体使用 1.1.添加fastjson2依赖 1.2.常用类和方法 1.3.将JSON字符串转换成对象 1.3.1.JSON字符串转换成对象 1.3.2.JSON字符串转换成数组 1.4.将对象转换成JSON字符串 1.4.1.将对象转换成JSON字符串 1.4.2.将数组转换成 JSON 字符串 2.性能测试报告 3.总结 …

浪潮发布G2平台

2017年2月28日下午&#xff0c;浪潮在北京粤财JW万豪酒店以“智变”为主题&#xff0c;发布新一代智能存储平台G2&#xff0c;该平台基于统一架构和In系列智能软件设计&#xff0c;在保障”三高”特性满足企业级关键数据存储、处理需求的同时&#xff0c;更强调数据生命周期的智…

第六章 部署WSUS及RDS服务

❄️作者介绍&#xff1a;奇妙的大歪❄️ &#x1f380;个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01;&#x1f380; &#x1f43d;个人简介&#xff1a;云计算网络运维专业人员&#x1f43d; 前言 适用范围&#xff1a;Windows Server 2022、Windows Server…

揭密ChatGPT背后团队鲜为人知的小秘密

ChatGPT引领的人工智能技术浪潮还在持续火爆&#xff0c;可是做出这款产品的OpenAI公司&#xff0c;熬得住多年的冷板凳&#xff0c;最终一飞冲天&#xff0c;他们是怎么做到的呢&#xff1f; 因此&#xff0c;我对这家企业的组织建设产生了浓厚的兴趣。我找啊找&#xff0c;最…

游戏开发日志13(利用PlayerPrefs来存储数据)

为游戏设置一个音量键&#xff0c;可以自由选择背景音乐是否开启&#xff0c;并且保存这个设置。 设计了UI如下&#xff1a; 其中BGM为Toggle&#xff0c;其余四个为Button 在canvas&#xff08;set&#xff09;上添加两个脚本&#xff1a;GameMnue&#xff0c;GameManage p…

【备战秋招】每日一题:4月15日美团春招第三题:题面+题目思路 + C++/python/js/Go/java带注释

为了更好的阅读体检&#xff0c;为了更好的阅读体检&#xff0c;&#xff0c;可以查看我的算法学习博客第三题-交通规划 在线评测链接:P1237 题目内容 塔子哥所在的国家有 n 个城市&#xff0c;这 n 个城市排成一列&#xff0c;按顺序编号为 1,2,3,...,n。然而&#xff0c;由…

【备战秋招】每日一题:4月8日美团春招第五题:题面+题目思路 + C++/python/js/Go/java带注释

为了更好的阅读体检&#xff0c;为了更好的阅读体检&#xff0c;&#xff0c;可以查看我的算法学习博客第五题-RGP种树 在线评测链接:P1170 题目描述&#xff1a; 塔子哥是一位著名的冒险家&#xff0c;他经常在各种森林里探险。今天&#xff0c;他来到了道成林&#xff0c;…

【Django 网页Web开发】24. 实战项目:moudleForm的文件上传应用到城市管理(17)(保姆级图文)

目录 用户上传文件存放media如何启用1. 在urls.py中进行配置&#xff1a;2. 在settings.py中进行配置&#xff1a;3. 能够通过media的url访问文件 moudleForm上传文件实现城市管理1. moudle.py2. url.py3. city.py4. city.html5. 文件上传小结6. 城市管理效果总结 欢迎关注 『D…

Vivado远程开发探索

平时主要用轻薄本办公&#xff0c;但是有时候又需要用Vivado做一些开发的工作&#xff0c;就感觉生产力不够。如果能在远程的高性能服务器上跑Vivado综合实现就好了。前段时间用ubuntu下安装的Vivado发现有一个Remote Host的设置。所以就准备折腾一下这个。 WSL WSL的安装看官…

chatgpt赋能python:Python怎么调成黑色背景?

Python怎么调成黑色背景&#xff1f; 随着人们对代码编辑器的要求越来越高&#xff0c;许多开发者都喜欢在黑色背景下编写代码。不仅仅是视觉审美方面考虑&#xff0c;黑色背景对眼睛的伤害也比浅色背景要小得多。本篇文章将介绍如何在Python中调整为黑色背景 介绍 默认情况…

[C++刷题之旅]反转链表

&#x1f338;心有所向&#xff0c;日复一日&#xff0c;必有精进 &#x1f338;专栏&#xff1a;C刷题之旅 &#x1f338;作者&#xff1a;早凉 目录 题目一&#xff1a;反转链表 【题目链接】 【题目描述】 【解题思路】 【代码实现】 进阶&#xff1a;链表中指定区间…

【异步】Futurn、FutureTask、CompletionService、CompletableFuture

1. Callable 在这篇文章中 【Thread】线程的基本概念及创建方式&#xff08;一&#xff09;&#xff0c;我们知道创建线程的几种方式。其中&#xff0c;有两个是通过接口来实现的&#xff1a;Runnable、Callable。它们的区别如下&#xff1a; Runnable 接口中的方法是没有返回…

代码审计——XXE详解

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 漏洞描述02 审计要点03 漏洞特征04 漏洞案例05 修复方案 01 漏洞描述 XXE&#xff08;XML External Entity Injection&#xff09;是一种针对XML终端实施的攻击&#xff0c;漏洞产生的根本原因就是…