next_permutation函数

例题1:P1088 [NOIP2004 普及组] 火星人

如果采用朴素的方法,每次都把火星人的排列初始化为原始排列再计算次数肯定会 \(\sf TLE\)

#include <bits/stdc++.h>

const int N = 1e4 + 5;
int a[N], b[N];
int n, m, cnt, t;

bool check(int x[], int y[]) {
	for (int i = 0; i < n; i++) {
		if (x[i] != y[i]) return false;
	}
	return true;
}

int main()
{
	std::cin >> n >> m;
	for (int i = 0; i < n; i++) std::cin >> a[i];
	
	for (int i = 0; i < n; i++) b[i] = a[i];
	std::sort(b, b + n);
	
	do {
		if (check(a, b)) break;
		cnt++;
	}while(std::next_permutation(b, b + n));
	
	cnt += m;
	std::sort(b, b + n);
	
	do {
		if (t == cnt) {
			for (int i = 0; i < n; i++) std::cout << b[i] << " ";
			break;
		}
		t++;
	}while(std::next_permutation(b, b + n));
}

image

所以应该从当前排列(就是火星人手指表示的那个序列)开始,做 \(m\) 次排列,即找按顺序排列的全排列中,排在当前序列之后 \(m\) 个的那个序列。

\(AC\) 代码:

#include <cstdio>
#include <algorithm>

const int N = 1e4 + 5;
int a[N], n, m;

int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) scanf("%d", &a[i]);
	
	while (m--) std::next_permutation(a, a + n); 
	
	for (int i = 0; i < n; i++) printf("%d ", a[i]);
	return 0;
}

例题2:HDU 1027

题目大意为输出序列 \(1 \sim N\) 的第 \(m\) 个全排列。

#include <cstdio>
#include <algorithm>

const int N = 1010;
int a[N];
int n, m, cnt;

int main()
{
	while (scanf("%d%d", &n, &m) != EOF) {
		for (int i = 0; i < n; i++) a[i] = i + 1;
		cnt = 0;
		do {
			if (cnt == m - 1) { 
				for (int i = 0; i < n; i++) printf("%d ", a[i]);
				puts("");
				break;
			}
			cnt++;
		}while(std::next_permutation(a, a + n));			
	}
	return 0;
}
posted @ 2024-03-31 00:26  胖柚の工作室  阅读(22)  评论(0)    收藏  举报