题目链接:点击打开链接
题目分析:类同白书p116
先贴下不可重复的排列如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
int i,data[4],len=0,j;
void print_permutation(int n,int *a,int cur)//利用递归的思想
{
int i,j;
if(cur==n)
{
for(i=0;i<=3;i++)
{
printf("%d",a[i]);
}
printf(" ");
}
else
for(i=0;i<=3;i++)
{
int ok=1;
for(j=0;j<cur;j++)
{
if(a[j]==data[i])
ok=0;
}
if(ok)
{
a[cur]=data[i];
print_permutation(4,a,cur+1);
}
}
}
using namespace std;
int main()
{
int a[4];
while(1)
{
for(i=0;i<=3;i++)
{
scanf("%d",&data[i]);
a[i]=-1;
if(data[i]==0)
len++;
}
if(len==4)//防止都为0的情况
break;
sort(data,data+4);
print_permutation(4,a,0);
}
return 0;
}
继续:生成可重集排列
由于枚举p中元素要不重不漏。
else for(i=0;i<n;i++)
if(!i&&p[i-1]!=p[i])
{
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[j]==p[i]) c2++;
if(c1<c2)
{
a[cur]=p[i];
print_permutation(n,p,a,cur+1);
}
}
边界什么的太恶心拉
#include <iostream>
#include <algorithm>
using namespace std;
int flag,flag_fir;
void print_permutation(int n,int *P,int *A,int cur){
int i,j;
if(cur==n){
if(A[0]){
if(A[0]!=flag){
if(!flag_fir)
cout<<endl;
flag_fir=0;
flag=A[0];
}
else cout<<" ";
for(i=0;i<n;i++)
cout<<A[i];
}
}
else for(i=0;i<n;i++)
if(!i||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[j]==P[i]) c2++;
if(c1<c2){
A[cur]=P[i];
print_permutation(n,P,A,cur+1);
}
}
}
int main()
{
int n,A[4],cur;
int P[4];
int S[1000][4];
int i;
for(i=0;;i++){
cin>>S[i][0]>>S[i][1]>>S[i][2]>>S[i][3];
if(!(S[i][0]||S[i][1]||S[i][2]||S[i][3]))
break;
}
for(int k=0;k<i;k++)
{
P[0]=S[k][0];
P[1]=S[k][1];
P[2]=S[k][2];
P[3]=S[k][3];
flag=-1;
flag_fir=1;
sort(P,P+4);
cur=0;
print_permutation(4,P,A,cur);
cout<<endl;
if(k!=i-1) cout<<endl;
}
return 0;
}