关于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- 关于N个鸡蛋M个篮子
- N个鸡蛋M个篮子
- N个鸡蛋分到M个篮子里
- N个鸡蛋放进M个篮子问题
- N个鸡蛋放进M个篮子问题
- N个鸡蛋放到M个篮子中
- 关于N个鸡蛋放在M个篮子里等系列问题详解
- N个鸡蛋放到M个篮子中,篮子不能为空
- N个鸡蛋放M个篮子,每个篮子不空,保证提不同组合的篮子能取出1至N个鸡蛋
- N个鸡蛋放入M个篮子且能组合出1~N所有的数
- 回溯法_求N个鸡蛋分到M个篮子里问题
- 164 求N个鸡蛋分到M个篮子里问题
- N个鸡蛋从M楼层摔(2个鸡蛋从100层摔)
- 2个鸡蛋从100层摔(N个鸡蛋从M楼层摔)
- N个鸡蛋从M楼层摔(2个鸡蛋从100层摔)
- 关于1000个鸡蛋放入10个篮子通过提篮子能得到1000当中的任意数
- 关于N个小球放M个盒子解答
- 关于将m个苹果放到n个盘子中
- [DEBUG]内存泄露调试
- 快速排序算法相关
- STL的erase操作
- gc野马通过压力测试(只有1K单位的容量,gc作用明显)
- Android 编译命令及选项
- 关于N个鸡蛋M个篮子
- split方法和转义字符
- 无法删除 找不到指定路径
- 固定点的另外三种变形
- 下载oracle
- 我对DDD的认知(一)
- 基于python的分词算法的实现(1) - 算法
- 通过崩溃地址找出源代码的出错行(转载)
- shuffle算法