zoukankan      html  css  js  c++  java
  • C语言------排列组合 组合情况(重复和不重复)

    组合不重复数

    问题引入:

    1.不重复的情况:

    例如ABCDE,让你从里面选出3个,问你一共有多少种可能,我们可以直接递归进行列举一共有多少种。下面看代码:

    #include<stdio.h>
    int m,n;
    
    int f(int m,int n)    //共有m个球 取n个球
    {
        if(n == m){        //当堆里的数目 和 我们想拿的相同时 只有一种情况 
            return 1;
        }
        
        if(n == 0){        //n=0 也是一种取法 
            return 1;
        } 
        
        return f(m-1,n-1) + f(m-1,n);    //从m-1的堆里取球 取到我们想要的再取n-1个 
                                        //否则再取n 
     } 
    int main()
    {
        printf("%d",f(5,3));
        return 0;
    }

    组合重复数

    问题引入:

    2 重复情况:

    例如AABBBC ,让你从这些字母中选出三个进行组合,你肯定不能枚举,这样你会发现打印出来有重复的。

    #include<stdio.h>
    int data[3];
    int x[3];

    int min(int a,int b) //返回最小值
    {
    if(a > b){
    return b;
    }

    if(b > a){
    return a;
    }
    }
    void work(int x[]) //打印数组
    {
    int i;
    for(i=0;i<3;i++){
    printf("%d",x[i]);
    }
    printf(" ");
    }

    void f(int data[],int x[],int k,int goal) //k为当前考虑的位置
    //goal距目标剩余位置
    {
    int i;
    if(k==3)
    {
    if(goal == 0){
    work(x);
    }

    return;
    }

    for(i=0;i<=min(data[k],goal);i++)
    {
    x[k] = i;
    f(data,x,k+1,goal-i);
    }

    x[k] = 0; //回溯

    }

    int main()
    {
    int data[3]={2,3,1}; //每个元素 的最大个数
    int x[3]; //每个元素 取到的个数

    f(data,x,0,3);
    return 0;
    }

    实例:2016年蓝桥杯 代码填空 抽签


    抽签

    X星球要派出一个5人组成的观察团前往W星。
    其中:
    A国最多可以派出4人。
    B国最多可以派出2人。
    C国最多可以派出2人。
    ....

    那么最终派往W星的观察团会有多少种国别的不同组合呢?

    下面的程序解决了这个问题。
    数组a[] 中既是每个国家可以派出的最多的名额。
    程序执行结果为:
    DEFFF
    CEFFF
    CDFFF
    CDEFF
    CCFFF
    CCEFF
    CCDFF
    CCDEF
    BEFFF
    BDFFF
    BDEFF
    BCFFF
    BCEFF
    BCDFF
    BCDEF
    ....
    (以下省略,总共101行)

    #include <stdio.h>
    #define N 6
    #define M 5
    #define BUF 1024
    
    void f(int a[], int k, int m, char b[])
    {
    int i,j;
    
    if(k==N){ 
    b[M] = 0;
    if(m==0) printf("%s
    ",b);
    return;
    }
    
    for(i=0; i<=a[k]; i++){
    for(j=0; j<i; j++) b[M-m+j] = k+'A';
    ______________________; //填空位置
    }
    }
    int main()
    {    
    int a[N] = {4,2,2,1,1,3};
    char b[BUF];
    f(a,0,M,b);
    return 0;
    }

    仔细阅读代码,填写划线部分缺少的内容。

    注意:不要填写任何已有内容或说明性文字。

    填空位置

            f(a,k+1,m-j,b);  //填空位置
    非学无以广才,非志无以成学。 正是因为今天的不完美,才对未来充满希望。 ----长帆
  • 相关阅读:
    TCP 协议如何解决粘包、半包问题 转载:https://mp.weixin.qq.com/s/XqGCaX94hCvrYI_Tvfq_yQ
    [国家集训队]happiness
    CF592D Super M
    [APIO2010]巡逻
    [NOI2012]美食节
    [JSOI2008]Blue Mary的旅行
    [十二省联考2019]D1T2字符串问题
    [十二省联考2019]D2T2春节十二响
    [十二省联考2019]D1T1异或粽子
    [WC2008]游览计划
  • 原文地址:https://www.cnblogs.com/changfan/p/10549177.html
Copyright © 2011-2022 走看看