算法:全排列(Full Permutation)-hdu1027

2 篇文章 0 订阅

全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

c++算法实现:

#include <iostream>
using namespace std;

const int MAXN = 1010;
int n;

void swap(int arr[],int p,int q)    //交换数据
{
    int temp=arr[p];
    arr[p]=arr[q];
    arr[q]=temp;
}

void print(int arr[],int k)        //输出数据
{
    for(int i=1; i<k; i++)
    {
        cout << arr[i] << " ";
    }
    cout << '\n';
}

void perm(int arr[],int p,int q)
{
    if(p==q)
    {
        print(arr,q+1);
    }
    else
    {
        for(int i=p; i<=q; i++)
        {
            swap(arr,p,i);           //交换数组里的两个数据
            perm(arr,p+1,q);         //每交换一次数据就进行一次排列
            swap(arr,p,i);           //值交换后还得再交换回来
        }
    }
}

int main()
{

    int arr[MAXN];

    while(cin>>n)
    {

        for(int i=1; i<=n; i++)
        {
            arr[i]=i;
        }

        perm(arr,1,n);

    }

    return 0;
}

在这里插入图片描述
函数perm利用递归进行排列
swap是把一个元素放到此下次排列的开头,从而达到元素交换的目的
第二次swap是把排列后的元素换回来,从而进行下一次排列
如此递归,最后能得到一个全排列


解此题的时候发现了一个STL: next_permutation !!! 用来求下一个排列组合

http://acm.hdu.edu.cn/showproblem.php?pid=1027

next_permutation()
一个数组:arr{a,b,c}
next_permutation(arr[0],arr[2])能返回 abc,acb,bac,bca,cab,cba
如果没有下一个排列组合,则返回false,否则返回true
每执行一次 next_permutation() 会把新的排列放在原来的空间里

AC代码:

#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN = 10010;
int m,n;
int a[MAXN];

int main()
{

    while(cin >> n >> m)
    {

        for(int i=1; i<=n; i++)
        {
            a[i]=i;                          //对数组进行赋值
        }





        for(int i=1; i<m; i++)               //求的是第m项,所以进行m-1次全排列
        {
            next_permutation(a+1,a+n+1);     //数组a的第1个至a+n+1个元素进行全排列
        }



        cout << a[1];
        for(int i=2; i<=n; i++)
        {
            cout << " " << a[i];             //输出数组
        }
        cout << endl;


    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值