当前位置: 首页 > article >正文

【贪心算法】洛谷P1106 - 删数问题

2025 - 12 - 26 - 第 46 篇
【洛谷】贪心算法题单 - 【贪心算法】 - 【学习笔记】
作者(Author): 郑龙浩 / 仟濹(CSND账号名)

目录

文章目录

  • 目录
  • P1106 删数问题
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例 #1
      • 样例输入 #1
      • 样例输出 #1
    • 提示
    • 思路
    • 代码

P1106 删数问题

题目描述

键盘输入一个高精度的正整数 n n n(不超过 250 250 250 位),去掉其中任意 k k k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 n n n k k k,寻找一种方案使得剩下的数字组成的新数最小。

输入格式

输入两行正整数。

第一行输入一个高精度的正整数 n n n

第二行输入一个正整数 k k k,表示需要删除的数字个数。

输出格式

输出一个整数,最后剩下的最小数。

样例 #1

样例输入 #1

175438 
4

样例输出 #1

13

提示

len ⁡ ( n ) \operatorname{len}(n) len(n) 表示 n n n位数,保证 1 ≤ k < len ⁡ ( n ) ≤ 250 1 \leq k < \operatorname{len}(n) \leq 250 1k<len(n)250

思路

删除任意k个数字以后,如何保证是最小的数呢,如何去掉呢????
思路是这样的,从做往右(高位到低位)依次两两比较,如果 arr[ i ] <= arr[ i + 1 ], 则无需管,直到遇到 arr[ i ] > arr[ i + 1 ], 这时候需要将 arr[ i + 1 ] 去掉
说白了,就是尽量让这个数字保持升序,这样才能保证最小 --> 高位数字小 --> 则整个数字小

所以,去掉的数字一般分为两种情况

  1. 在 i ~ num - 1 的范围内, 【有】 arr[ i ] > arr[ i + 1 ] 的清况 --> 去掉arr[ i + 1 ]
  2. 在 i ~ num - 1 的范围内, 【无】 arr[ i ] > arr[ i + 1 ] 的清况 --> 去掉最后一位 --> 为什么是去掉最后一位呢,因为数字顺序为升序的时候,最右侧的数字是最大的,所以去掉
    ( 第 2 种情况 也无需再单独去判断了,因为内层循环中如果找不到arr[ i ] <= arr[ i + 1 ],退出循环的时候,i 会定位在 倒数第二个元素上面 )

最右侧的数字相当于 --> 整个高精度正数少了一位 + 少了最大的数

程序过程:

  1. 最外层循环:用来控制循环次数 --> 循环 k 次 --> 删掉 k 个数字
  2. 最内层循环:用来寻找 arr[ i ] < arr[ i + 1 ] 的情况,如果遇到,则退出循环,将 i 定位在 5 处( 比如 1 2 3 4 5 1 ),退出循环以后将 5 删除即可

借用的函数: erase(a, b) --> 删除函数 --> STL容器

高峰期–> 我的理解就是 从左往右依次两两比较,只要遇到不是 arr[ i ] <= arr[ i + 1 ] 而是 arr[ i ] > arr[ i + 1 ], 则 arr[ i ] 就是这个高峰期
简单点说,就是尽可能的让高位数字的顺序为升序 --> 因为 高位数字小, 则整个 高精度数字 就小

变量:
arr --> 存放高精度正整数
k --> 要删除的数字的数量
i --> 决定 高峰 的位置

代码

// 洛谷P1106 删数问题
// 作者: 郑龙浩 / 仟濹(CSDN)
// 时间:2025 - 01 -22
// 键盘输入一个高精度的正整数 n(不超过 250 位),去掉其中任意 k 个数字后剩下的数字按原左右次序将组成一个新的非负整数。编程对给定的 n 和 k,
// 寻找一种方案使得剩下的数字组成的新数最小。

// 看的这个大佬的题解,我才会这么做的 https://www.luogu.com.cn/article/qgschm0n

// 思路:
// 删除任意k个数字以后,如何保证是最小的数呢,如何去掉呢????
// 思路是这样的,从做往右(高位到低位)依次两两比较,如果 arr[ i ] <= arr[ i + 1 ], 则无需管,直到遇到 arr[ i ] > arr[ i + 1 ], 这时候需要将 arr[ i + 1 ] 去掉
// 说白了,就是尽量让这个数字保持升序,这样才能保证最小 --> 高位数字小 --> 则整个数字小

// 所以,去掉的数字一般分为两种情况
// 1. 在 i ~ num - 1 的范围内, 【有】 arr[ i ] > arr[ i + 1 ] 的清况 --> 去掉arr[ i + 1 ]
// 2. 在 i ~ num - 1 的范围内, 【无】 arr[ i ] > arr[ i + 1 ] 的清况 --> 去掉最后一位 --> 为什么是去掉最后一位呢,因为数字顺序为升序的时候,最右侧的数字是最大的,所以去掉
// ( 第 2 种情况 也无需再单独去判断了,因为内层循环中如果找不到arr[ i ] <= arr[ i + 1 ],退出循环的时候,i 会定位在 倒数第二个元素上面 )

// 最右侧的数字相当于 --> 整个高精度正数少了一位 + 少了最大的数、
// 程序过程:
// 1. 最外层循环:用来控制循环次数 --> 循环 k 次 --> 删掉 k 个数字
// 2. 最内层循环:用来寻找 arr[ i ] < arr[ i + 1 ] 的情况,如果遇到,则退出循环,将 i 定位在 5 处( 比如 1 2 3 4 5 1 ),退出循环以后将 5 删除即可

//借用的函数:erase(a, b) --> 删除函数 --> STL容器

// 高峰期 --> 我的理解就是 从左往右依次两两比较,只要遇到不是 arr[ i ] <= arr[ i + 1 ] 而是 arr[ i ] > arr[ i + 1 ], 则 arr[ i ] 就是这个高峰期
// 简单点说,就是尽可能的让高位数字的顺序为升序 --> 因为 高位数字小, 则整个 高精度数字 就小

// 变量:
// arr --> 存放高精度正整数
// k --> 要删除的数字的数量
// i --> 决定 高峰 的位置

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int main( void ){
    string arr; // 表示的 高精度正整数
    int k; // 表示的 要删除的数字数量
    cin >> arr >> k;
    while( k ){
        // 寻找 高峰期
        int i;
        for( i = 0; arr[ i ] <= arr[ i + 1 ] && i < arr.size() - 1; i ++ ); // 非常简洁 --> 寻找 高峰期(第一次知道这个词语,从题解中看到的,因为我自己不知道用什么词语可以表达找到的这个元素)
        arr.erase( i, 1 ); // 从第 i 个位置连续删 1 个元素
        k --;
    }
    // 处理前导零 --> 如果本来的 高精度正整数 前面几个为0,则不能将其打出来, 应该将它们去掉
    while( arr [ 0 ] == '0' && arr.size() > 1 ) {//处理前导零, 并且保证如果数字为0,则必须保留一位0 
    arr.erase( 0, 1 );
	}
    cout << arr;
    return 0;
}

http://www.kler.cn/a/514960.html

相关文章:

  • 微信小程序使用上拉加载onReachBottom。页面拖不动。一直无法触发上拉的事件。
  • deep face cam 部署报错解决
  • Fastapi + vue3 自动化测试平台(4)-- fastapi分页查询封装
  • FPGA 开发工作需求明确:关键要点与实践方法
  • 汽车钥匙发展史
  • PyQt5 超详细入门级教程上篇
  • oracle好用的decode語法
  • Frida+Objection
  • 科技护航:分布式 IO 模块与大型 PLC,稳筑地铁安全防线
  • jupyter配置说明
  • 【2024年华为OD机试】 (E卷,200分) - 跳格子3 (JavaScriptJava PythonC/C++)
  • Spring注解篇:@GetMapping详解
  • 金融波动率的多模型建模研究:GARCH族与HAR模型的Python实现与对比分析
  • Springboot3 自动装配之核心文件:imports文件
  • Spring 依赖注入详解:创建 Bean 和注入依赖是一回事吗?
  • 【JAVA】BOSS系统发版艺术:构建高效、优雅的微服务部署策略
  • mq_open创建队列失败
  • Flink在流处理中,为什么还会有窗口的概念呢
  • 全球化趋势与中资企业出海背景
  • Spring MVC和Spring WebFlux的区别
  • Linux系统总结
  • 前沿技术对比:大模型技术为什么发展远快于区块链技术,中英对照解释
  • 2.6 createCmd中的builder建造者设计模式
  • 【Maui】提示消息的扩展
  • HTB:Heist[WriteUP]
  • HTML5 History API