最小新正数(贪心)

原题:

给定一个十进制正整数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;
}

代码写得挺简洁的,应好好参考。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值