8605 删数问题
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0
题型: 编程题 语言: G++;GCC;VC;JAVA
Description
问题描述:
给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列成一个新的正整数。
算法设计:
给定n (1<=n<=200)位的正整数a和k,此时,k小于n。
试着设计一个算法,找出删去k个数,剩下数字组成的新数最小的删数方案。
输入格式
可输入多组测试数据(不超过50组测试数据),每组测试数据分两行,每行一个数,数的含义如下。
第一行:正整数a(a是大于0的一个n位正整数)
第二行:正整数k
以0来结束测试数据。
输出格式
输出每组测试数据所得出的删k位数之后的最小数。
若输出的数首位是0,无须理会,0也直接输出即可。例如:024,就直接输出024,无须改成24。
输入样例
178543
4
87654321
2
123456789
1
254193
1
90249
2
0
输出样例
13
654321
12345678
24193
024
解题思路
贪心算法
利用“最陡下降点”优先,即每次找到第一个元素,使其满足大于下一个元素。正如上述的那个例子,第一个删除的是9,因为9>0;
得到的整数是17806;第二个删除的是8,因为8>0,得到的整数是1706,第三个删除的是7,因为7>0,得到的整数是106;
第四个删除的是1,因为1>0,得到的是06,为正确的答案。
算法思路
- 输入 a 时判断是否等于0,不是0才继续下面的步骤
- 外层 for 循环记录删到第几个数
- 内层 while 循环通过指针 j 一直从字符串头往后遍历,找到第一个满足大于后一个数的数即可,即 a[j] <= a[j + 1]
- 通过 string 自带的删除函数 erase() 删除即可
更多注释可查看下方的完整代码中,有助于理解。
代码如下
#include <iostream>
using namespace std;
int main()
{
string a;
int k;
while(true) {
cin >> a;
if(a == "0")
break;
cin >> k;
int i, j;
// i 记录删了几个数了
for(i = 0; i < k; i++) {
// 每次删,j 都从头开始遍历
j = 0;
// 找到第一个前一个大于后一个的数
while(j < a.size() - 1 && a[j] <= a[j + 1])
j++;
a.erase(j, 1);
}
cout << a << endl;
}
return 0;
}
最后
对我感兴趣的小伙伴可查看以下链接
- 我的掘金主页:https://juejin.cn/user/1302297507801358
- 博客主页:http://blog.zhangjiancong.top/
- 公众号:Smooth前端成长记录