搜索常用(枚举子集,全排列(有序无序,可重不可重))

    技术2024-01-29  101

    全排列(有序无重)

    /*全排列板子 */ #include<stdio.h> int a[10],n,hash[10]={0}; void dfs(int step) { if(step==n+1) { for(int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); return; } for(int i=1;i<=9;i++) { if(hash[i]==0) { a[step]=i; hash[i]=1; dfs(step+1); hash[i]=0;//只有线性才会用这个,非线性用反而错了 } } return; } int main() { scanf("%d",&n); dfs(1); return 0; }

    全排列(有序有重)

    //生成可重集的排列(这个要求是排好序的) #include <cstdio> #include <cstring> int num[10] = {0}; void print_permutation(int n,int * A,int * P,int cur) { if(n == cur) { for(int i = 0;i < n;i ++) printf("%d ",A[i]); printf("\n"); } else for(int i = 0;i < n;i ++) if(!i || P[i] != P[i - 1])//保证不会114重复两次 (这是功能)实际工作原理是这一次这一位选他下次就不选他了 { int c1 = 0; for(int j = 0;j < cur;j ++) if(A[j] == P[i]) c1++; if(c1 < num[P[i]]) { A[cur] = P[i]; print_permutation(n,A,P,cur + 1); } } } int main() { int A[10],P[10],n; scanf("%d",&n); for(int i = 0;i < n;i ++) { scanf("%d",&P[i]); num[P[i]] ++; //有点像桶排序的方法 } print_permutation(n,A,P,0); return 0; } ———————————————— 原文链接:https://blog.csdn.net/Wendy____/article/details/75208938

    枚举子集(无序不重复)

    //这个东西递归的好一步一步修改回溯 void print_subset(int n, int* A, int cur) { for(int i = 0; i < cur; i++) printf("%d ", A[i]); //打印当前集合 printf("\n"); int s = cur ? A[cur-1]+1 : 0; //确定当前元素的最小可能值 for(int i = s; i < n; i++) { A[cur] = i; print_subset(n, A, cur+1); //递归构造子集 } }

    二进制版的(虽然行数少但是因为是循环的所以不好修改)

    //枚举子集无顺序 #include<iostream> #include<stdio.h> using namespace std; void print_subset(int n,int s) { for(int i=0;i<n;i++)//对n进行扫描性搜查 (0到n-1) { if(s&(1<<i)) printf("%d ",i); } printf("\n"); } int main() { int n; scanf("%d",&n); for(int i=0;i<(1<<n);i++) print_subset(n,i);//2的n次方-1是 return 0; }
    Processed: 0.009, SQL: 9