【ACwing】一、基础算法:1.3 递归枚举(排列型)

94. 递归实现排列型枚举

在这里插入图片描述
相当于一个不重复序列的全排列问题,图示如下:
在这里插入图片描述

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int x[10]; //标记当前是否被选择过
int num[10];//记录当前所选数据
void dfs(int current)
{
    if(current>n)//到达叶子结点输出结果
    {
        for(int i=1; i<=n; i++)
            cout<<num[i]<<' ';
        cout<<endl;
        return ;
    }

    for(int i=1;i<=n;i++)//遍历每个数
    {
        if(x[i]==0)//未被选择过
        {
            num[current]=i;
            x[i]=1;
            dfs(current+1);

            //回溯时恢复
            x[i]=0;
        }
    }
}
int main()
{
    cin>>n;
    dfs(1);
    return 0;
}
/*
输入:
3
*/

输出

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

1537. 递归实现排列类型枚举 II

在这里插入图片描述

此题和上一个题类似,只是num数组赋值的时候应该为a[i],此外还需要考虑输出结果重复的情况,为了方便排除重复情况先将输入的数组a进行排序,使得重复的数字相接,同时要设置 “当前数=前一个数&&上一个数未被选中” 则跳过当前数的选择。这样若前后两个数相同,则必须保证其放入x数组的顺序,使得重复的排列被去掉。

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n;
int x[10]; //标记当前是否被选择过
int num[10],a[10];//记录当前所选数据
void dfs(int current)
{
    if(current>n)//到达叶子结点输出结果
    {
        for(int i=1; i<=n; i++)
            cout<<num[i]<<' ';
        cout<<endl;
        return ;
    }

    for(int i=1; i<=n; i++) //遍历每个数
    {
        //如果前一个数和当前数相同,且上一个数未被被选中则不进行当前数的选择
        if(a[i-1]==a[i] && x[i-1]==0)
            continue;

        if(x[i]==0) //未被选择过
        {
            num[current]=a[i];
            x[i]=1;
            dfs(current+1);

            //回溯时恢复
            x[i]=0;
        }
    }
}
int main()
{
    cin>>n;
    for(int i=1; i<=n; i++)
        cin>>a[i];

    sort(a,a+n+1);
    dfs(1);
    return 0;
}
/*
3
1 2 2
*/

输出

1 1 2
1 2 1
2 1 1
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值