淘宝笔试题:
有N个蛋和M个篮子,把蛋放到M个篮子里,每个篮子都不能为空。另外,需要满足:任意一个小于N的正整数,都能由某几个篮子内蛋的数量相加的和得到。写出程序,使得输入一个(N,M),输出所有可能的分配情况
#include "StdAfx.h" #include <iostream> #include <math.h> using namespace std; #define MAX 1000 int ans[MAX]; int count = 0; int cal = 0; //如果前x的篮子已经放了y个鸡蛋,则第x+1个篮子可以放1到y+1个鸡蛋,(如果放y+2,则取不出y+1) //第x+2个篮子可以放(y+y+1)+1=2y+2 //第x+3个篮子可以放(2y+2+y+1+y)+1=4y+4,这样我们可以从0开始 ,依次开始遍历所有存放情况 void dfs(int hasEgg,int nextBasketIndex,int totalEgg,int totalBasket,int last){ if(hasEgg==totalEgg && nextBasketIndex==totalBasket){ for(int i=0;i<totalBasket;i++){ printf("%d ",ans[i]); } printf("\n"); count++; return ; } if(nextBasketIndex>=totalBasket||hasEgg>=totalEgg){ return; } //剪枝1:如果后面的所有篮子都用最小数来填充 都比总数大 if(hasEgg+last*(totalBasket-nextBasketIndex)>totalEgg)return; //剪枝2:如果后面的所有篮子都用最大数来填充 还是不够大 if((hasEgg+1)*(pow(2,totalBasket-nextBasketIndex)-1)+hasEgg<totalEgg)return; for(int i=last;i<=hasEgg+1;i++){ ans[nextBasketIndex] = i; cal++; dfs(hasEgg+i,nextBasketIndex+1,totalEgg,totalBasket,i); } } int solve(int egg,int basket){ if(egg>pow(2,basket)||basket>egg) return 0; dfs(0,0,egg,basket,1); return count; } void main(){ solve(16,10); printf("结果:%d\n运算次数:%d\n",count,cal); }