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

这道题可以使用贪心算法来解决,核心思路是尽量让高位的数字尽可能小。当我们逐步删除数字时,会优先删除高位中相对较大的数字。具体做法是从左到右遍历数字序列,当发现当前数字比它后面的数字大时,就删除当前数字,直到删除了S个数字或者遍历完整个序列。如果遍历完后删除的数字个数还不够S个,就从序列的末尾继续删除。

【算法思路】

  1. 输入处理 :使用 string 类型存储高精度的正整数 num,并读取要删除的数字个数 s

这道题为什么用字符串存储而不是数组存储?

处理大整数的便利性 :题目中明确提到输入的是一个高精度的正整数,且不超过 250 位。普通的整数类型(如 intlong long)所能表示的数值范围是有限的,无法存储如此大的数字。字符串可以轻松地存储任意长度的数字序列,它本质上是字符数组,每个字符对应数字的一位,不受数值范围的限制。例如,对于一个 200 位的大整数,使用字符串可以直接将其按位存储,不会出现溢出问题。

操作的灵活性 :在本题中,需要进行删除数字的操作。字符串提供了方便的方法来删除指定位置的字符,例如在 C++ 中可以使用 erase 函数。对于字符串 str,可以使用 str.erase(i, 1) 轻松删除第 i 个位置的字符。

cpp 复制代码
//数组存储
vector<int> num(n);
int k;
for(int i=0;i<n;i++){
	cin>>num[i];
}
cin>>k;

//字符串存储
string num;
int k;
cin>>num>>k;
  1. 删数操作
  • 进入一个循环,循环次数为 k 次。
  • 在每次循环中,从左到右遍历 num,找到第一个满足 num[i] > num[i + 1] 的位置 i,然后删除该位置的数字。
  • 如果内层循环结束后 deleted 仍然为 false,说明在当前数字字符串中没有找到递减的位置,此时使用 num.erase(num.length() - 1, 1) 删除字符串的最后一个字符,并将 k 减 1。
  1. 去除前导零:删数操作完成后,可能会出现前导零的情况,因此需要去除前导零。

    • 定义int类型的变量start变量初始化为0,用于记录数字字符串中第一个非零字符的位置。
    • 进入 while (start < num.length() && num[start] == '0') 循环,从字符串的开头开始遍历,只要没有遍历到字符串末尾且当前字符是0,就将start加1。
    • 用三目运算符处理前导零并且给num赋予合适的值。
  2. 输出结果 :如果去除前导零后 num 为空,说明最终结果为 0,输出 0;否则输出 num

【代码示例】

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;

int main(){
	string num;
	int k;
	cin>>num>>k;
	
	//进行k次删除操作 
	while(k > 0){
		bool deleted=false;//标记是否找到递减位置 
		for(int i=0;i < num.length()-1;++i){
			if(num[i] > num[i+1]){
				//找到第一个递减的位置,删除改位置的数字
				num.erase(i,1);
				deleted=true;
				k--;
				break;
			}
		}
		//如果没找到递减位置,删除末尾字符 
		if(!deleted){
			num.erase(num.length() - 1,1); 
			k--;
		}
	}
	
	//去除前导零
	int start=0;
	while (start < num.length() && num[start] == '0'){
		start++;
	}
	num = (start==num.length()) ? "0" : num.substr(start);
	
	cout<<num<<endl; 
	return 0;
}

注意:

  • 边界处理:若序列完全递增,删除末尾数字

  • substr:是 std::string 类的一个成员函数,num.substr(start) 会返回从字符串 num 的第 start 个位置开始一直到字符串末尾的子字符串。

相关推荐
杰克尼5 分钟前
2. 两数相加
算法
无聊的小坏坏6 分钟前
单调栈通关指南:从力扣 84 到力扣 42
c++·算法·leetcode
_Coin_-13 分钟前
算法训练营DAY29 第八章 贪心算法 part02
算法·贪心算法
阿维同学22 分钟前
自动驾驶关键算法深度研究
人工智能·算法·自动驾驶
YOLO大师34 分钟前
华为OD机试 2025B卷 - 小明减肥(C++&Python&JAVA&JS&C语言)
c++·python·华为od·华为od机试·华为od2025b卷·华为机试2025b卷·华为od机试2025b卷
今天背单词了吗9801 小时前
算法学习笔记:11.冒泡排序——从原理到实战,涵盖 LeetCode 与考研 408 例题
java·学习·算法·排序算法·冒泡排序
看到我,请让我去学习2 小时前
OpenCV编程- (图像基础处理:噪声、滤波、直方图与边缘检测)
c语言·c++·人工智能·opencv·计算机视觉
倔强的小石头_4 小时前
【C语言指南】函数指针深度解析
java·c语言·算法
Yasin Chen4 小时前
C# Dictionary源码分析
算法·unity·哈希算法
_Coin_-5 小时前
算法训练营DAY27 第八章 贪心算法 part01
算法·贪心算法