删数问题(一本通1321)
题目描述
键盘输入一个高精度的正整数 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
【算法分析】
一开始会想,先对数字进行排序,然后按序输出,会得出从小到大的数字序列。
就像这样
cin>>n>>k;
for(int i=0;i<strlen(n);i++){
a[i]=i;
}
for(int i=0;i<strlen(n)-1;i++){
for(int j=i+1;j<strlen(n);j++){
if(n[i]>n[j]){
swap(a[i],a[j]);
}
}
}
for(int i=0;i<strlen(n)-k;i++){
cout<<n[a[i]];
}
然后我们就会发现,这个结果只能通过三个测试点,只针对部分数据。
这里忽略了一个重点要求----->去掉其中任意 k k k 个数字后剩下的数字按原左右次序将组成一个新的非负整数.
需要改变一下策略:可以从前到后去删除数据,每一次删掉较大的。
完整的代码如下:
#include<bits/stdc++.h>
using namespace std;
char n[255];
int a[255];
int k;
int main(){
cin>>n>>k;
int k1=k;
int len=strlen(n);
while(k--){
for(int i=0;i<len-1;i++){
if(n[i]>n[i+1]){
//删除较大的数
for(int j=i;j<len-1;j++){
n[j]=n[j+1];//移动数据
}
break;//删除一个数据进行下一次循环
}
}
len--;//字符串长度-1
}
//cout<<n;
//去掉前导零
int j=0,m=len;
while(n[j]=='0'&& m>1){
j++;m--;
}
for(int i=j;i<len;i++){
cout<<n[i];
}
return 0;
}