全排列函数

按字典序从小到大输出这个字符串的全排列样例输入abc样例输出abc
acb
bac
bca
cab
cba

组合数学中经常用到排列,这里介绍一个计算序列全排列的函数:
next_permutation(start,end),和prev_permutation(start,end)。
这两个函数作用是一样的,区别就在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列。
至于这里的“前一个”和“后一个”,我们可以把它理解为序列的字典序的前后,严格来讲,就是对于当前序列pn,他的下一个序列pn+1满足:不存在另外的序列pm,使pn

下面就是两个蓝桥杯例题:
(刚开始可能觉得毫无头绪,但只要掌握这个函数,题就变得非常简单)

一、3.凑算式
凑算式 B DEF A + — + ------- = 10 C GHI
(如果显示有问题,可以参见【图1.jpg】)

这个算式中AI代表09的数字,不同的字母代表不同的数字。

比如:
6+8/3+952/714 就是一种解法,
5+3/1+972/486 是另一种解法。

这个算式一共有多少种解法?

注意:你提交应该是个整数,不要填写任何多余的内容或说明性文字。
修正:AI代表19的数字
全排列函数_第1张图片
答案:29

思路:对ABCDEFGHI进行全排列,只要符合和等于10就sum++。
代码如下:

//全排列函数:全排列函数next_permutation 对数字进行全排列 
#include
#include
#include
using namespace std;
int main()
{
 double a[9]={1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0};
 int sum=0;
 do
 {
      if(a[0]+a[1]/a[2]+(a[3]*100+a[4]*10+a[5])/(a[6]*100+a[7]*10+a[8])==10.0)
         sum++;
 }while(next_permutation(a,a+9));
 printf("%d",sum);
 return 0;
}

二、方格填数
方格填数 如下的10个格子 ±-±-±-+ | | | | ±-±-±-±-+ | | | | | ±-±-±-±-+ | | | | ±-±-±-+
(如果显示有问题,也可以参看【图1.jpg】)

填入0~9的数字。
要求:连续的两个数字不能相邻。

(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

请填写表示方案数目的整数。

注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

全排列函数_第2张图片
答案:不重复:1580

代码如下:

//要求连续两个数字不能相邻(左右,上下,对角都算相邻) 
#include
#include
#include
#include
using namespace std;
int main()
{
 int sum=0;
 int s[10]={0,1,2,3,4,5,6,7,8,9};
 do
 {
  int flag=1;
  //左右相邻 
  if(abs(s[0]-s[1])==1||abs(s[2]-s[1])==1||abs(s[3]-s[4])==1||abs(s[4]-s[5])==1||abs(s[5]-s[6])==1||abs(s[8]-s[7])==1||abs(s[9]-s[8])==1)
     flag=0;
  //上下相邻 
  if(abs(s[0]-s[4])==1||abs(s[5]-s[1])==1||abs(s[2]-s[6])==1||abs(s[3]-s[7])==1||abs(s[4]-s[8])==1||abs(s[5]-s[9])==1)
     flag=0;
  //对角相邻
  if(abs(s[0]-s[3])==1||abs(s[5]-s[0])==1||abs(s[1]-s[6])==1||abs(s[1]-s[4])==1||abs(s[5]-s[2])==1||abs(s[3]-s[8])==1||abs(s[9]-s[4])==1||abs(s[5]-s[8])==1||abs(s[9]-s[6])==1||abs(s[4]-s[7])==1)
     flag=0; 
  if(flag==1)
     sum++;
 }while(next_permutation(s,s+10));
 printf("%d",sum);
 return 0;
 }

你可能感兴趣的:(蓝桥杯)