next_permutation函数用法及例题(洛谷p1618,p1706,p1088)

next_permutation是algorithm标准库中的一个标准函数,它可以表示[start,end)内存的数组中产生严格的下一个字典序排列。具体来说[2,3,1]变为[3,1,2][3,2,1]

next_permutation只能获得下一个排列,如果要获得全排列,那么就需要先对数组进行升序排序

基本定义如下:
next_permutaion(起始地址,末尾地址+1)
next_permutaion(起始地址,末尾地址+1,自定义排序)

可以使用默认的升序排序,也可以使用自定义的排序方法
这点和sort(应该都知道这个函数吧,不知道的可以去查阅一些大佬的博客)基本一样,也是可以自定义排序方法

自定义排序大家可以去观看其他一些大佬的博客,因为知道这些我们就可以完成题目上面的这三道例题了

P1706:P1706 全排列问题 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题就是对next_permutation函数很基本的一个应用,你要会用的话是不是直接就秒了呢哈哈,直接贴代码

#include<iostream>
using namespace std;
#include<algorithm>
#include<iomanip>
int main() {
	int a[10];
	for (int i = 0; i < 10; i++) {
		a[i] = i + 1;
	}
	int n;
	cin >> n;
	do {
		for (int i = 0; i < n; i++) {
			cout << setw(5) << a[i];
		}
		cout << "\n";
	} while (next_permutation(a, a + n));
	return 0;
}

应该是不需要过多的解释,大家不懂的可以问我。

P1088 [NOIP2004 普及组] 火星人 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

别看题目臭长臭长的,但实际上和上一道大同小异,上一道题求得是全排列,这道题求得是中间固定的一个排列顺序。

#include<algorithm>
#include<iostream>
using namespace std;
int a[10000];
int main() {
	int N, M;
	cin >> N >> M;
	/*for (int i = 0; i < 10000; i++) {
		a[i] = i + 1;
	}*/
	int b = 1; \
		for (int i = 0; i < N; i++)
			cin >> a[i];
	while (b-1 != M) {
		next_permutation(a, a + N);
		b++;
	}
	for (int i = 0; i < N; i++)
		cout << a[i] << " ";
	return 0;
}

注意看我循环的条件,为什么是b-1!=M因为我刚开始其实是b!=M然后我就发现不对,每回都差一个,然后就加了一个-1.至于为啥差一个我也不是很清楚了,感觉是题目的问题,因为按

这个表格里是不用的,但是案例里的又必须要减个一。。。

P1618 三连击(升级版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这个题其实我前两天就已经写过博客了,当时是用着暴力枚举的方法,讲解也很清晰,有需要的同学可以去看看洛谷P1618三连击(升级版)(C++)-CSDN博客(王婆卖瓜,自卖自夸)

今天这道题换一种更简单的方法来实现,就是用库函数。

思路就是把全排列里的9个数分别划给3个3位数就可以产生所有情况了。代码如下

#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int a[9];
	for (int i = 0; i < 9; i++)
		a[i] = i+1;
	int A, B, C;
	cin >> A >> B >> C;
	int score = 0;
	do {
		int x, y, z;
		x = a[0] * 100 + a[1] * 10 + a[2];
		y = a[5] + a[4] * 10 + a[3] * 100;
		z = a[8] + a[7] * 10 + a[6] * 100;
		if (x * B == y * A && x * C == z * A)
		{
			cout << x << " " << y << " " << z << "\n";
			score++;
		}
			
	} while (next_permutation(a, a + 9));
	
	if (score == 0) {
		cout << "No!!!";
	}
	return 0;
}

注意,下面这块角标是不能改的,改了之后情况是没错,但是出答案的顺序和题目要求的不一样

总结:这篇文章主要是讲了库函数的使用以及一些简单例题的讲解,如果掌握了函数的用法,这几道例题应该问题不大,其实这几类题都属于排列枚举的范畴,而排列枚举,我们可以首先考虑能否通过使用这个函数来简化思路。

如果有帮助还请点个赞,有问题的话可以评论捏

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值