原题:
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。 现在从m位中***删除k位***(0<k < m),求生成的新整数最小为多少? (注意这里是删除,不是重排)
例如: n = 9128456, k = 2, 则生成的新整数最小为12456
Input 第一行t, 表示有t组数据; 接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
Output t行,每行一个数字,表示从n中删除k位后得到的最小整数。 Sample Input 2 9128456 2 1444 3 Sample Output 12456 1
分析:最终得到的数有m-k位,那么贪心的策略可以是:先使m-k位上的数字最小,再使m-k-1上的最小,如此下去,直到到了个位。
伪代码有点难写,写一下大致流程吧:
1.以字符串为处理对象,输入为字符串s[],输出为字符串ans[];
2.以n=9128456为例,m=7,k=2,s[0]=‘9’,s[1]=‘1’, … ,s[6]=‘6’,最终的数有m-k=5位。由于原题要求是删除,所以我们只能够从n的第7位到第5位检索最小的数,找到后位置标记为flag,再从flag+1到第4位检索,重复操作,直至第1位,即个位。观察到k=2时,s[k]即为第5位,s[k+1]即为第4位,因此,我们可以以k为对象,设置一个循坏,循坏结束标记是k>m-1。
代码如下:
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,m,k,flag;
char s[15],ans[15],c;
int i,j;
scanf("%d",&t);
while(t--)
{
flag=j=0;
scanf("%s %d",s,&k);
m=strlen(s)-1;
while(k<=m) //以k为循坏处理对象
{
for(i=flag;i<=k;i++)
{
if(i==flag) c=s[i];
else if(c>s[i]){
c=s[i];flag=i;
}
}
ans[j++]=c;
flag++;k++; //flag要加1,k也要递增1
// printf("%c %d\n",c,flag);
}ans[j]='\0';
printf("%s\n",ans);
}
return 0;
}
代码写得挺简洁的,应好好参考。