<span style="font-family: Verdana, Tahoma, Arial, sans-serif; background-color: rgb(250, 252, 255);">Description</span>
给定n位正整数a,去掉其中任意k个数字后,剩下的数字按原次序排列成一个新的正整数。
算法设计:
给定n (1<=n<=200)位的正整数a和k,此时,k小于n。
试着设计一个算法,找出删去k个数,剩下数字组成的新数最小的删数方案。
输入格式
可输入多组测试数据(不超过50组测试数据),每组测试数据分两行,每行一个数,数的含义如下。
第一行:正整数a(a是大于0的一个n位正整数)
第二行:正整数k
以0来结束测试数据。
第一行:正整数a(a是大于0的一个n位正整数)
第二行:正整数k
以0来结束测试数据。
输出格式
输出每组测试数据所得出的删k位数之后的最小数。
若输出的数首位是0,无须理会,0也直接输出即可。例如:024,就直接输出024,无须改成24。
若输出的数首位是0,无须理会,0也直接输出即可。例如:024,就直接输出024,无须改成24。
输入样例
4
87654321
2
123456789
1
254193
1
90249
2
0
输出样例
13
654321
12345678
24193
024
654321
12345678
24193
024
简单贪心,其实就是从左往右寻找递减区间,一旦找到就删除,如果数列为递增区间,就直接删除后K个数
例如:67048201845
当k=1时,从左往右找到7>0,所以删除7,得6048201845
当k=2时,从新的数列中找到6>0,得048201845
当k=3时,从数列找到8>2,得04201845
以此类推。。。
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
using namespace std;
#define N 1001
int a[N];
char s[N];
int find(int *a,int n)
{
int i=n-1;
while(a[i]==-1) //找最后一个非-1的数
{
i--;
}
int e=i; //e为最后一个非-1的数
i=0;
int t,s;
while(i<e)
{
while(a[i]==-1) //从左往右找第一对逆序对
{
i++;
}
t=i;i++;
while(a[i]==-1)
{
i++;
}
s=i;
if(a[t]>a[s])
{
return t;
}
}
return e;
}
int main()
{
int k;
while(~scanf("%s",s))
{
int len=strlen(s);
if(len==1&&s[0]=='0')
break;
else
{
cin>>k;
for(int i=0;i<len;i++)
a[i]=s[i]-'0';
for(int i=0;i<k;i++)
{
int ans=find(a,len);
a[ans]=-1;
}
for(int i=0;i<len;i++)
if(a[i]!=-1)
cout<<a[i];
cout<<endl;
}
}
return 0;
}
本文介绍了一种针对给定n位正整数a,在保留原数位顺序不变的前提下,通过删除k个数字来构造出最小可能数值的算法实现。该算法采用贪心策略,从左至右扫描并移除构成递减区间的数字。
1866

被折叠的 条评论
为什么被折叠?



