枚举生成可重集的排列

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int a[N],p[N];
void print_permutation(int n,int *p,int *a,int cur)
{
int i,j;
if(cur==n)
{
for(i=0; i<n; i++)
printf("%d ",a[i]);
printf("\n");
}
else
{
for(i=0; i<n; i++)
if(p[i]!=p[i-1])
{
int c1=0,c2=0;
for(j=0; j<cur; j++)
if(a[j]==p[i])
c1++;
for(j=0; j<n; j++)
if(p[i]==p[j])
c2++;
if(c1<c2)
{
a[cur]=p[i];
print_permutation(n,p,a,cur+1);
}
}
}
}
int main()
{
int n,i;
while(scanf("%d",&n))
{
for(i=0; i<n; i++)
scanf("%d",&p[i]);
sort(p,p+n);
print_permutation(n,p,a,0);
}
return 0;
}

时间: 2024-11-06 07:18:29

枚举生成可重集的排列的相关文章

生成可重集的排列

下面给出自己编写的代码: 1 #include<stdio.h>  2 int P[100],A[100];   3 void print_permutation(int n,int* P,int* A,int cur)  4 {    5 int i, j;  6 if(cur == n)  7 {  8 for(i = 0; i < n; i++)  9 printf("%d ", A[i]);      10 printf("\n");  1

生成可重集的排列(方法)

通过暴力或者dfs的方法可以很容易地得到n个数的全排列,可生成可重集的呢,例如给出一个数组a[],要求输出这个数组的全排列,与普通的求全排列不同,数组中很可能存在重复的数,所以方法都需要改一改: DFS #include"iostream"#include"cstring"#include"cstdio"using namespace std;int n,book[21],a[21];int ca=1; void dfs(int step){if

C++ P2830 生成可重集的排列(算法竞赛P185)

//直接在P1183的基础上做几处改动: #include<iostream>#include<cstdio>using namespace std; int p[15],n,m;int sign[15],ap[15];//标记数组: void outans()//输出函数 { for(int i=1;i<=m;i++) printf("%d ",p[i]); printf("\n"); return;}void DFS(int x)/

算法入门经典-第七章 例题7-2-2 可重集的排列

可重:如果问题变成输入数组p,并按字典序输出数组A个元素的所有全排列,则需要修改代码集的全排列 // Rujia Liu #include<cstdio> #include<algorithm> using namespace std; int P[100], A[100]; // 输出数组P中元素的全排列.数组P中可能有重复元素 void print_permutation(int n, int* P, int* A, int cur) { if(cur == n) { for(

生成可重集的排序 (白书P184)

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int ans[6]; int book[6],a[6],n; void dfs(int cnt) { int i,j; if(cnt==n) { for(i=0;i<n;i++) if(!i) printf("%d",ans[i]); else

C++ P2832 生成可重集的子集

#include<iostream>#include<cstdio>using namespace std; int n,m,vis[15],num[15];//vis[i]代表数字i在全集中出现的总次数,num[i]为i在子集中出现的次数: void data_in(){ scanf("%d%d",&n,&m); int x; for(int i=1;i<=n;i++) { scanf("%d",&x); vi

暴力搜索专题小结:全排列及可重集排列生成算法

1~n的全排列 (1)思路:按照递归的思想,初始化集合S中含有1~n所有元素.如果1~n的集合S为空,那么输出全排列:否则从小到大依次考虑每个元素i,在A的末尾添加i后,集合S变为S-{i}.这里我们不需要集合S,只需要利用一个变量cur表示当前位要填的数即可.那么A中没有出现过的元素均可以选择. #define N 100 int A[N]; void print_permutation(int n, int*A, int cur) { if (cur == n) { for (int i =

1151 - Buy or Build(二进制枚举子集 + 并查集)

这题LRJ书上翻译的有问题,书上说两点之间的cost是两点的欧几里得距离,而题目要求两点的距离是两点欧几里得距离的平方. 其余就没什么好说的了,裸的并查集,需要注意的就是二进制枚举子集的问题. 二进制枚举子集: for(int i = 0 ; i < (1 << s) ; i++){ /*s是集合元素的个数*/ for(int j = 0 ; j < s ; j++){ if(!(s >> j) & 1) continue; else{ } } } 140548

POJ 1256 Anagram(输入可重集枚举排序)

[题意简述]:本题题意很好理解!题目给出的Hint,使我们对关键点有了更加清晰的认识 An upper case letter goes before the corresponding lower case letter. So the right order of letters is 'A'<'a'<'B'<'b'<...<'Z'<'z'. 就是给一个序列(序列可以有重复的元素),让我们输出它的所有排列,字母顺序规定给出! [分析]:这道题是我之前学习枚举排序和子