hdu 1716(排列2)

题目链接:点击打开链接

题目分析:类同白书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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值