洛谷P1157 组合的输出

原题链接

image

题解:

本题有两种办法解决,第一种 使用stl中 next_permutation函数

#include "iostream"
#include "algorithm"
#include "iomanip"
using namespace std;
int main(){
    int x,n,flag[25]={0};
    cin>>x>>n;
    for(int j=n;j<x;j++)flag[j]=1;
    do{
        for(int i=0;i<x;i++){
            if(flag[i]==false)
                cout<<setw(3)<<i+1;
        }
        cout<<endl;
    } while (next_permutation(flag,flag+x));
	//使用do while 输出本身,然后再求下一排列
}

next_permutation函数本来是用来求出给定范围内下一排列,但是在这道题目中有一个问题,
题目要求 在5个数里找3个数,而这个函数如果求1~5的全排列,那么就会输出以下内容:

1 2 3 4 5
1 2 3 5 4
1 2 4 3 5
1 2 4 5 3
等等

此时输出前三位就会出现重复 因为后两位也参与排序
所以 使用一个状态数组来进行排列,1代表不可输出,0代表可输出
然后使用内置函数对这个状态数组求排列,就可以实现求组合
for(int j=n;j<x;j++)flag[j]=1;这一行是让最后x-n个数设置为1
此时状态码为 0 0 0 1 1输出 1 2 3
对状态数组求排列
下一次的状态码是0 0 1 0 1 输出 1 2 4
对状态数组求排列
下一次的状态码是0 0 1 1 0 输出 1 2 5
以此类推 便实现了从数组里 拿出指定个数进行组合的算法
所以 以后需要求组合的时候 也可以使用这种办法

第二种 使用DFS

待后续补充

posted @ 2023-01-15 19:19  Cheng_Mao  阅读(50)  评论(0编辑  收藏  举报