算法问题,找数

问题描述:从一个正整数M中去掉任意S位后,就会得到一个新的正整数(保留各位数字的相对位置不变)去掉不同位上的数字就会得到不同的新整数,其中有一个最小的正整数N,问题是:再利用最小新整数N的各位数字所组成的新整数中,找出大于N的最小整数,若不存在这样的数,测输出0.例如,位长位6的正整数175838,去掉任意3位后得到的最小整数为138,由1、3、8三个数字组成的整数包括138、183、318、381、813、831其中大于138的最小整数是183,所以输出183。


解题思路:第一步是先从高位开始,向低位逐个比较,若当前位的数字大于低一位的数字,则删除当前位,此时能保证删除后剩余各位组成的整数最小。若最后也没找到

满足条件的位,则删除最低位。

第二步:在剩余数各位的所有排列中寻找当前最小数的下一个排列数。这里没必要去求出所有的排列后再去寻找。从最低位开始,想高位逐位比较,若当前位大于前一位,则需要将当前位之前之后的所有大于前一位数字中的最小值与当前位的前一位交换,然后对从当前位到最低位的各位数字从小到大排序。否则,将当前位移到前一位继续以上比较,当到达最高位还没有找到满足条件的位时,则说明此数为所有排列中的最大数。




/*
write by liuqian  2016 04 08 
问题描述:从一个正整数M中去掉任意S位后,就会得到一个新的正整数(保留各位数字的相对位置不变)
去掉不同位上的数字就会得到不同的新整数,其中有一个最小的正整数N,问题是:再利用最小新整数N的
各位数字所组成的新整数中,找出大于N的最小整数,若不存在这样的数,测输出0.例如,位长位6的正整数
175838,去掉任意3位后得到的最小整数为138,由1、3、8三个数字组成的整数包括138、183、318、381、813、831
其中大于138的最小整数是183,所以输出183
*/


#include <iostream>
#include <string>
#include <algorithm>
using namespace std;


/*
方法:从最高位开始,向低位逐个比较,若当前位的数字大于低一位的数字,则删除当前位,此时能保证删除后剩余各位组成的整数最小;
否则将当前位移动到低一位继续以上比较,若到最后也没找到满足条件的位,则删除最低位。
*/
void deleteMaxNum(string &str, const int len)
{//删除一个字母使剩余组成的数最小
int i, j;
for (i = 0; i < len; i++)
{
for (j = 0; j < str.size()-1; j++)
if (str[j]>str[j+1])
break;
str.erase(j, 1);
}
}


/*
查找下一个更大的数, 如当前数为1324,下一个更大的数为1342
方法:从末尾开始往前遍历,若当前位大于前一位,则需要将当前位之后(即已遍历过的那些数字)的所有大于前一位数字中的最小值与前一位交换,
然后对当前位到最低位的各位数字从小到大排序
*/
void findNextMoreLargeNum(string &str)
{//查找下一个更大的排列
int i, j;
for (i = str.size()-1; i > 0; i--)
if (str[i]>str[i-1])
break;


if (i == 0)
str = "0";
else
{
for (j = i; j < str.size(); j++)
if (str[j] <= str[i - 1])
break;


swap(str[i - 1], str[j - 1]);
char *strTemp = &str[i];
sort(strTemp, &str[str.size()]);
}
}


int main()
{
int celi_num;//测例数目
int d_len;//要删除的数目
string str;
cin >> celi_num;
while (celi_num--)
{
cin >> str >> d_len;
deleteMaxNum(str, d_len);
findNextMoreLargeNum(str);
cout << str << endl;
}
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值