nyoj 19-擅长排列的小明(STL-next_permutation())

19-擅长排列的小明


内存限制:64MB 时间限制:1000ms Special Judge: No
accepted:10 submit:16

题目描述:

小明十分聪明,而且十分擅长排列计算。比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他,在这5个数字中选出几个数字让他继续全排列,那么你就错了,他同样的很擅长。现在需要你写一个程序来验证擅长排列的小明到底对不对。

输入描述:

第一行输入整数N(1<N<10)表示多少组测试数据,
每组测试数据第一行两个整数 n m (1<n<9,0<m<=n)

输出描述:

在1-n中选取m个字符进行全排列,按字典序全部输出,每种排列占一行,每组数据间不需分界。如样例

样例输入:

2
3 1
4 2

样例输出:

1
2
3
12
13
14
21
23
24
31
32
34
41
42
43

分析:
  根据全排列的性质,一组包含所有组合的全排列(ps:假设该组数由n个元素组成,我们要从中选择m个元素,问它的组合情况),
  它所对应的前m个元素,就是它的所有选择、组合情况

扩展:
  equal(A, A+m, B);
  //用于比较数组A和数组B是否相同,即就是取数组A的前m个元素与数组B做比较

步骤:
  ①、初始化A为1到n组成的数组
  ②、通过STL中的next_permutation()创建数组A的全排列
  ③、如果下一个排列与上一个排列不同就用temp来存放下一个排列

核心代码:

 1 do
 2 {
 3     if(!equal(A, A+m, temp))
 4     {
 5         for(int i = 0; i < m; ++ i)
 6         {
 7             temp[i] = A[i];
 8             printf("%d", temp[i]);
 9         }
10         printf("\n");
11     }
12 } while(next_permutation(A, A+n));

 

C/C++代码实现(AC):

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <stack>
 7 #include <map>
 8 #include <queue>
 9 
10 using namespace std;
11 const int MAXN = 12;
12 int A[MAXN];
13 
14 void cal_array(int n)
15 {
16     for(int i = 0; i < n; ++ i)
17         A[i] = i + 1;
18 }
19 
20 int main()
21 {
22     int t;
23     scanf("%d", &t);
24     while(t --)
25     {
26         int n, m, temp[MAXN] = {0};
27         scanf("%d%d", &n, &m);
28         cal_array(n);
29 
30         do
31         {
32             if(!equal(A, A + m, temp)) // 如果数组A的前m个元素与temp两个数组不想等
33             {
34                 for(int i = 0; i < m; ++ i)
35                 {
36                     temp[i] = A[i];
37                     printf("%d", temp[i]);
38                 }
39                 printf("\n");
40             }
41         } while(next_permutation(A, A + n));
42     }
43     return 0;
44 }

 

posted @ 2018-05-20 13:58  GetcharZp  阅读(199)  评论(0编辑  收藏  举报