zoukankan      html  css  js  c++  java
  • 递归基础_全排列+改写_组合数

    C: 全排列问题

    描述

    生成一个1..N的全排列. 

    输入

    第一行包括一个数字 n 小于 9

    输出

    按字典序输出1...N的所有全排列.

    样例

    输入: 3

    输出: 123 132 213 231 312 321(a,b,c)

    状态转移方程为: A(n, n)=A(n,1)(组合+)A(n-1,1)....A(1,1)

    实现全排列和组合不一样的地方在于,对于(a,b,c)——(a,b)的遍历 不需要设置 a (表头)的上限,

    只需要要求已经置入的数不再重复即可——因为组合可以用上界来限制,而这个表达比较困难,所以用bool数组标记来表示

    代码如下,固定第一个数

     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <map>
     7 #include <algorithm>
     8 typedef long long ll;
     9 using namespace std;
    10 int n;
    11 int a[11];
    12 bool x[11];
    13 void f(int it,int num) {
    14 //num表示此时已经排列了几层(栈的深度)
    15 //it表示下一个要压入的数
    16     a[num]=it;//入栈
    17     x[it]=1;//mark
    18     if(num==n) {
    19         for(int j=1; j<=n; j++) {
    20             cout<<a[j]<<" ";
    21         }
    22         printf("
    ");
    23     } else {
    24         for(int i=1; i<=n; i++) {
    25             if(x[i]==1)continue;
    26             else f(i,num+1);
    27         }
    28     }
    29     x[it]=0;
    30 }
    31 
    32 int main () {
    33     cin>>n;
    34     memset(x,0,sizeof(x));
    35     for(int i=1; i<=n; i++) {
    36         f(i,1);
    37     }
    38 
    39     return 0;
    40 }
    View Code

     从0位开始

     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <map>
     7 #include <algorithm>
     8 typedef long long ll;
     9 using namespace std;
    10 int n;
    11 int a[11];
    12 bool x[11];
    13 void f(int it,int num) {
    14 //num表示此时已经排列了几层(栈的深度)
    15 //it表示下一个要压入的数
    16     a[num]=it;//入栈
    17     x[it]=1;//mark
    18     if(num==n) {
    19         for(int j=1; j<=n; j++) {
    20             cout<<a[j]<<" ";
    21         }
    22         printf("
    ");
    23     } else {
    24         for(int i=1; i<=n; i++) {
    25             if(x[i]==1)continue;
    26             else f(i,num+1);
    27         }
    28     }
    29     x[it]=0;
    30 }
    31 
    32 int main () {
    33     cin>>n;
    34     memset(x,0,sizeof(x));
    35 
    36     f(0,0);
    37 
    38 
    39     return 0;
    40 }
    View Code

    改写成组合数,就是利用 1234 123 124 134, 每次后面一位都比前面大因此,此时不再从1开始,而是从上一个it+1开始找

     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <map>
     7 #include <algorithm>
     8 typedef long long ll;
     9 using namespace std;
    10 int n;
    11 int r;
    12 int a[11];
    13 bool x[11];
    14 void f(int it,int num) {
    15 //num表示此时已经排列了几层(栈的深度)
    16 //it表示下一个要压入的数
    17     a[num]=it;//入栈
    18     x[it]=1;//mark
    19     if(num==r) {
    20         for(int j=1; j<=r; j++) {
    21             cout<<a[j]<<" ";
    22         }
    23         printf("
    ");
    24     } else {
    25         for(int i=it+1; i<=n; i++) {
    26             if(x[i]==1)continue;
    27             else f(i,num+1);
    28         }
    29     }
    30     x[it]=0;
    31 }
    32 
    33 int main () {
    34     cin>>n>>r;
    35     memset(x,0,sizeof(x));
    36     for(int i=1; i<=n-r+1; i++) {
    37         f(i,1);
    38     }
    39 
    40     return 0;
    41 }
    View Code

     进一步简化

     1 #include <iostream>
     2 #include <cstring>
     3 #include <queue>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <map>
     7 #include <algorithm>
     8 typedef long long ll;
     9 using namespace std;
    10 int n;
    11 int r;
    12 int a[11];
    13 bool x[11];
    14 void f(int it,int num) {
    15 //num表示此时已经排列了几层(栈的深度)
    16 //it表示下一个要压入的数
    17     a[num]=it;//入栈
    18     x[it]=1;//mark
    19     if(num==r) {
    20         for(int j=1; j<=r; j++) {
    21             cout<<a[j]<<" ";
    22         }
    23         printf("
    ");
    24     } else {
    25         for(int i=it+1; i<=n; i++) {
    26             if(x[i]==1)continue;
    27             else f(i,num+1);
    28         }
    29     }
    30     x[it]=0;
    31 }
    32 
    33 int main () {
    34     cin>>n>>r;
    35     memset(x,0,sizeof(x));
    36     
    37     f(0,0);
    38     
    39 
    40     return 0;
    41 }
    View Code

     

     

     

     

    老实一点,可爱多了
  • 相关阅读:
    Android 重写系统Crash处理类,保存Crash信息到SD卡 和 完美退出程序的方法
    LeetCode第二十四题-交换链表中节点值
    LeetCode第二十三题-合并n个有序链表
    LeetCode第二十二题-创建n对括号
    LeetCode第二十一题-对两个有序链表排序
    LeetCode第二十题-有效的括号
    LeetCode第十九题-链表节点的删除
    LeetCode第十八题-四数之和
    LeetCode第十七题-电话号码的字母组合
    LeetCode第十六题-找出数组中三数之和最接近目标值的答案
  • 原文地址:https://www.cnblogs.com/KID-yln/p/12529307.html
Copyright © 2011-2022 走看看