关于N个鸡蛋M个篮子

来源:互联网 发布:pdf转换dwg软件 编辑:程序博客网 时间:2024/04/30 12:35

题目:将N个鸡蛋装入M个篮子,保证每个篮子都不能为空,且对于任意给定的小于N的整数,均有几个篮子的鸡蛋个数和与之相等,请给出所有可能的装法。设用f(N, M)表示该问题的解决方案,设想将N/2个鸡蛋装入前面i个篮子里,则后面的M-i个篮子中鸡蛋可以任意排列,只要保证不为空即可,设g(n, m)表示该排列,其中n表示鸡蛋个数,m表示篮子个数。所以,初始问题f(N,M) = f(N/2, i) U g(N - N / 2, M - i);其中i的取值可以为[up_log(N/2), M-1], up_log(n)表示对n取对数并向上取整。g(n, m) 也是一个递归函数,具体见如下实现:

Back
#include <stdio.h>#include <stdlib.h>#define MAX 100#define RS_SIZE 1000int eggs[MAX];int rs[RS_SIZE][MAX];int label = 1;int up_log (int n);void g (int eggs, int start, int end, int cons_m);void printResult (int end);void solution (int N_eggs, int M_basket, int cons_m);void resume (int end);void sort (int a[], int n);int find (int a[], int rs[][MAX], int end, int label);int up_log (int n) {    int i = 0;    int k = 1;    while (k < n) {        k <<= 1;        i++;    }    return i;}void solution (int N, int M, int cons_m) {    int i;    int k;    if (M == 1 && N > 1) {        resume(M);        return;    }    if ( M < up_log (N) ) {        resume(M);        return;    }    if (M > N) {        resume(M);        return;    }    if ( M == N ) {        for (i = 0; i < M; i++)            eggs[i] = 1;        if (M == cons_m)            printResult (cons_m);        return;    }    if (N == M + 1) {         for (i = 0; i < M; i++)            eggs[i] = 1;         eggs[M - 1] = 2;        if (M == cons_m)            printResult (cons_m);        return;    }    k = (up_log(N / 2)) ? up_log( N / 2) : 1;    for (i = k; i < M; i++) {        solution (N / 2, i, cons_m);        g (N - N / 2, i, M - 1, cons_m);    }}void g (int eggs_num, int start, int end, int cons_m) {    int i;    if (start > end)        return;    if (!eggs_num)        return;    if ( start == end ) {        eggs[end] = eggs_num;        if (eggs[0] && (end + 1) == cons_m)            printResult (cons_m);        return;    }    if (end - start + 1 > eggs_num)        return;    else {        for (i = 1; i <= eggs_num -end + start; i++) {            eggs[start] = i;            g (eggs_num - i, start + 1, end, cons_m);        }    }}void printResult (int end) {    int i;    int in_rs_array = 0;    int tmp[MAX];    for (i = 0; i < end; i++)        tmp[i] = eggs[i];    sort (tmp, end);    if (label > 1)        in_rs_array = find (tmp, rs, end, label - 1);    if (!in_rs_array) {        printf ("Method %d: ", label);        for (i = 0; i < end; ) {            printf ("%4d", tmp[i]);            rs[label - 1][i] = tmp[i];            if ( ++i % 10 == 0 )                printf ("/n");        }        printf ("/n");        label++;    }}void resume (int end) {    int i;    for (i = 0; i < end; i++)        eggs[i] = 0;}void sort (int a[], int n) {    int i, j;    int temp;    int swap = 1;    for (i = 0; i < n - 1; i++) {        swap = 0;        for (j = 0; j < n - i - 1; j++)            if (a[j + 1] < a[j]) {                temp = a[j];                a[j] = a[j + 1];                a[j + 1] = temp;                swap = 1;            }        if (!swap)            break;    }}int find (int a[], int rs[][MAX], int end, int label) {    int i, j;    for (i = 0; i < label; i++)        for (j = 0; j < end; j++) {            if (a[j] == rs[i][j] && j == end - 1)                return 1;            if (a[j] != rs[i][j])                break;        }    return 0;}int main (int argc, char **argv) {    int eggs, basket;    printf ("Please input number of eggs and baskets:/n");    scanf("%d%d", &eggs, &basket);    resume (basket);    solution (eggs, basket, basket);    if ( label == 1)        printf ("No solution found!/n");    exit (0);}
Top
原创粉丝点击