杭电OJ 1027(C++)

本文介绍了一种计算字符串第M个全排列的方法,包括手动实现的全排列算法和利用C++ STL中的next_permutation函数。通过具体示例代码展示了如何找到字符串的下一个全排列,最终达到目标全排列。

本题计算一个字符串的第M个全排列,组合数学中计算一个字符串的下一个全排列的算法如下:

  1. 从尾部开始往前寻找两个相邻的元素,前一个元素为 i,后一个元素为 j,且 i<j;
  2. 从后往前找第一个大于 i 的元素 k,将第 i、k 个元素对调;
  3. [j,last] 范围的元素倒转(颠倒排列)。

使用上述的全排列算法,AC代码如下:

#include <iostream>
using namespace std;

void fullPermutation(int arr[], int n); //计算字符串的下一个全排列

int main()
{
	int N, M;
	int arr[1010];
	while (cin >> N >> M)
	{
		memset(arr, 0, sizeof(arr));
		for (int i = 1; i <= N; i++)
			arr[i] = i;

		M--; //字符串的第一个全排列为其自身
		while (M--) //计算第M个全排列
			fullPermutation(arr, N);

		cout << arr[1];
		for (int i = 2; i <= N; i++)
			cout << " " << arr[i];
		cout << endl;
	}

	return 0;
}

void fullPermutation(int arr[], int n) //计算字符串的下一个全排列
{
	int i;
	for (i = n - 1; i > 0; i--) //从尾部开始往前寻找两个相邻的元素,前一个元素为 i,后一个元素为 j,且 i<j
	{
		if (arr[i] < arr[i + 1])
			break;
	}
	for (int j = n; j > 0; j--) //从后往前找第一个大于 i 的元素 k,将第 i、k 个元素对调
	{
		if (arr[j] > arr[i])
		{
			int temp = arr[j];
			arr[j] = arr[i];
			arr[i] = temp;
			break;
		}
	}
	int mid = (i + n) / 2;
	for (int k = i + 1; k <= mid; k++) // [j, last] 范围的元素倒转(颠倒排列)
	{
		int temp = arr[k];
		arr[k] = arr[n - k + i + 1];
		arr[n - k + i + 1] = temp;
	}
}

C++ STL有一个函数 next_permutation 专门计算字符串的下一个全排列,AC代码如下:

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

int main()
{
	int N, M;
	int arr[1010];
	while (cin >> N >> M)
	{
		memset(arr, 0, sizeof(arr));
		for (int i = 1; i <= N; i++)
			arr[i] = i;

		M--; //字符串的第一个全排列为其自身
		while (M--) //计算第M个全排列
			next_permutation(arr + 1, arr + N + 1);

		cout << arr[1];
		for (int i = 2; i <= N; i++)
			cout << " " << arr[i];
		cout << endl;
	}

	return 0;
}

继续加油。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值