The Next Permutation C++

題目描述

For this problem, you will write a program that takes a (possibly long) string of decimal digits, and outputs the permutation of those decimal digits that has the next larger value (as a decimal number) than the input number. For example: 123 -> 132 279134399742 - 279134423799 It is possible that no permutation of the input digits has a larger value. For example, 987.

輸入格式:

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. Each data set is a single line that contains the data set number, followed by a space, followed by up to 80 decimal digits which is the input value.

輸出格式:

For each data set there is one line of output. If there is no larger permutation of the input digits, the output should be the data set number followed by a single space, followed by the string BIGGEST. If there is a solution, the output should be the data set number, a single space and the next larger permutation of the input digits.

輸入樣例

3
1 123
2 279134399742
3 987

輸出樣例

1 132
2 279134423799
3 BIGGEST

這道題的意思就是說給你一個字符串數字x,能否將數字位置交換得到一個最小且大於x的字符串數字y,然後輸出序號+得到的字符串數字y
這道題的解法其實可以先思考一下,要想得到一個最小的字符串數字,則要找一個數從左往右最靠右側較小的數字和從右側開始數大於該數的數字進行交換,279134399742像這個例子,從左往右可以發現3和從右往左的4進行交換,交換後得到279134499732,此時必然是大於原先的字符串數字,但是要想得到最小的字符串數字,則要將279134499732中4的右側數的小數放在前面,利用遞歸進行循環可以進行交換,我比較喜歡c++裏的string做這道題。
然後這個題理解一下其實不難,當然感覺學校的oj測試用例有些弱,不知道遇到大數的時候這個遞歸會不會死掉,當然題目說最多隻有80個字符數字,那其實問題不大,AC了就行。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<stdio.h>
#include<cmath>
using namespace std;
string line;
void dfs(int left){
	if(left>=line.size()){
		return;
	}
	char a;
	for(int i=left;i<line.size();i++){	
		for(int j=line.size()-1;j>left;j--){
			if(line[i]>line[j]){
				a = line[i];
				line[i] = line[j];
				line[j] = a;
			}
		}
	}
	left++;
	dfs(left);
}
main()
{
	int n,list;
	cin>>n;
	while(n--){
		cin>>list>>line;
		int leftN=-1,rightN=line.size();
		for(int i=0;i<rightN;i++){//從左往右
			for(int j=line.size()-1;j>i;j--){	//從右往左,到i過就行,要找的範圍段一直在leftN後
				if(line[j]>line[i]&&i>leftN){
					leftN=i;	//找到最小的進行交換
					rightN=j;
				}
			}
		}
		if(leftN==-1){
			cout<<list<<" BIGGEST"<<endl;	//如果leftN沒有改變那就說明沒有交換的數字
		}else{
			char a;
			a = line[leftN];	
			line[leftN] = line[rightN];
			line[rightN] = a;	//交換
			dfs(leftN+1);	//遞歸
			cout<<list<<" "<<line<<endl;
		}
	}
}

我的代碼可能有點難理解,上面的解釋有點亂,挺菜的也不知道怎麼講,就將就看,有什麼問題請大家指出。互啄一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章