12.C++: next_permutation与prev_permutation函数
(1)一般形式:
next_permutation(start,end,compare method)
(2)功能
找出当前排列以后的所有排列
(3)包含头文件
#include<algorithm>
(4)函数原型
#include <algorithm>
bool next_permutation(iterator start,iterator end)
当当前序列不存在下一个排列时,函数返回false,否则返回true
next_permutation函数的原理如下:
在当前序列中,从尾端向前寻找两个相邻元素,前一个记为*i,后一个记为*t,并且满足*i < *t。然后再从尾端
寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第t个元素之后(包括t)的所有元
素颠倒排序,即求出下一个序列了。
template<class Iterator>
bool next_permutation(Iterator first,Iterator last)
{
if(first == last)
return false;
Iterator i = first;
++i;
if(i == last)
return false;
i = last;
--i;
while(1)
{
Iterator t = i;
--i;
if(*i < *t)
{
Iterator j = last;
while(!(*i < *--j));
iter_swap(i,j);
reverse(t,last);
return true;
}
if(i == first)
{
reverse(first,last);
return false;
}
}
}
(4)几点说明
next_permutation(start,end,compare method)
第三个参数是比较方法,如果省略不写,则默认为升序,char型默认为字典序,也可以自定义比较方法。
1.几个例子
洛谷P1036
题目描述
将 1,2,…,9 共 9 个数分成三组,分别组成三个三位数,且使这三个三位数的比例是 A:B:C,试求出所有满足条件的三个三位数,若无解,输出 No!!!
。
输入格式
三个数,A,B,C。
输出格式
若干行,每行 3 个数字。按照每行第一个数字升序排列。
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<math.h>
#include<cstring>
#include<cstdio>
#include<cctype>
using namespace std;
int t[10] = { 0,1,2,3,4,5,6,7,8,9 };
int main()
{
int a, b, c;
cin >> a >> b >> c;
int sum = a * b * c;
a = sum / a;
b = sum / b;
c = sum / c;
int check = 0;
do {
if ((100 * t[1] + 10 * t[2] + t[3]) *a == (100 * t[4] + 10 * t[5] + t[6]) * b && (100 * t[1] + 10 * t[2] + t[3]) * a == (100 * t[7] + 10 * t[8] + t[9]) * c)
{
cout << t[1] << t[2] << t[3] << " " << t[4] << t[5] << t[6] << " " << t[7] << t[8] << t[9] << endl;//输出
check++;
}
} while (next_permutation(t + 1, t + 10));
if (check==0)cout << "No!!!";
}
本题利用next_permutation函数便很好解决