2019年清华软院推免考试(校外直博&校内硕/博) 第二题——超长整数排列(Arrange)

问题描述

2018年清华软院推免考试(校外直博&校内硕/博)

第二题——超长整数排列(Arrange

 

输入一个任意长度的数字序列,如果将数字序列的每一位看做一个单独的数字,则每个序列都可以看做是由数字0~9组成的一个排列。输出比输入序列大的最小排列,如果这样的序列不存在,则输出输入序列。

示例:

Input

123

Output

132

Explanation

"1""2""3"组成的排列从小到大有123,132,213,231,312,321,其中大于123的最小者是132

(因为是考后回忆,可能记忆有些模糊了,题干和代码都有可能有错,忘谅解)

------------------------------------------------------------

思路

由于事先不知道输入序列的长度,因此可以用std::string读取输入,记作s。

算法比较简单,从个位开始往前遍历,如果存在相邻两位(不妨记作第i位和第i+1位)使得s[i] < s[i+1],则将s[i]与s[i+1 : s.length()-1]中比s[i]大的最小者交换,再将交换后的s[i+1 : s.length()-1]升序排列即可得到比s大的排列中的最小者。算法复杂度是O(NlogN)

------------------------------------------------------------

代码

//输入一个任意长度的数字序列,如果将数字序列的每一位看做一个单独的数字,则每个序列都可以看做是由数字0~9组成的一个排列。
//输出比输入序列大的最小排列,如果这样的序列不存在,则输出输入序列。

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

int main()
{
	string s;
	cin >> s;
	int n = s.length(), i, j, minid;
	char a, minv;
	for (i=n-2; i>=0; i--)
	{
		if (s.at(i) < s.at(i+1))
		{
			// 找s[i+1 : s.length()-1]中比s[i]大的最小者
			minv = '9' + 10;
			minid = i + 1;
			a = s.at(i);
			for (j = i+1; j < n; j++)
			{
				if (s.at(j) > a && s.at(j) < minv)
				{
					minv = s.at(j);
					minid = j;
				}
			}
			swap(s.at(i), s.at(minid));
			sort(s.begin() + i + 1, s.end());
			break;
		}
	}
	cout << s;
	return 0;
}

 

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/82717930