1. 程式人生 > >中石油訓練賽第三次新生賽 E題取數排列

中石油訓練賽第三次新生賽 E題取數排列

題目描述

取1到N共N個連續的數字(1≤N≤9),組成每位數不重複的所有可能的N位數,按從小到大的順序進行編號。當輸入一個編號M時,就能打印出與該編號對應的那個N位數。例如,當N=3時,可組成的所有三位數為:
在這裡插入圖片描述
那麼,輸入編號M=2時,則輸出132。

輸入

包括兩個數,即正整數N(1 <= N <= 9)和正整數M(1 <= M <= 362880)。

輸出

只有一行,即與輸入的編號M對應的那個N位數。

樣例輸入
複製樣例資料 3 2

樣例輸出
132

這個題的思路是先把全部的排列找出來,然後輸出第幾個排列。可以利用next_permutation(全排列函式)函式生成全部的排列。
詳細說一下全排列函式的用法和注意事項:
函式名

:next_permutation 求下一個排列組合
函式模板:next_permutation(arr, arr+size);
引數說明
 arr: 陣列名
 size:陣列元素個數
函式功能: 返回值為bool型別,噹噹前序列不存在下一個排列時,函式返回false,否則返回true,排列好的數在陣列中儲存
注意:在使用前需要對欲排列陣列按升序排序,否則只能找出該序列之後的全排列數。
(舉個例子,如果陣列內的數是{1,2,3},生成的所有全排列是{123,132,213,231,312,321},但如果陣列內的數是{2,3,1},生成的所有全排列是{231,312,321})。
程式碼如下:

#include <cstdio>
#include <algorithm>
using namespace std;
int b[362880][9];
int main()
{
	int n,m;
	int a[9];
	int i,k=0;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	a[i]=i+1;
	for(int i=0;i<n;i++)
		b[k][i]=a[i]; //用b儲存生成的所有全排列,這裡注意兩點,一是函式是生成下一個全排列,所以第一個我們自己儲存一下,也就是這個迴圈,另一點是用的時候要保證陣列a內的數字有序,這裡顯然是有序的就不用管了。
k++; while(next_permutation(a,a+n)) //函式的返回值為bool型,引數為參與全排列的陣列名和陣列元素個數 { for(int i=0;i<n;i++) b[k][i]=a[i]; //繼續用b儲存生成的全排列 k++; } for(int i=0;i<n;i++) printf("%d",b[m-1][i]); return 0; }