淘宝实习生 笔试算法题 装鸡蛋

 

在网上看到的第一批笔试里面的一个算法编程题。

问题:有N个蛋和M个篮子,把蛋放到M个篮子里,每个篮子都不能为空。另外,需要满足:任意一个小于N的正整数,都能由某几个篮子内蛋的数量相加的和得到。写出程序,使得输入一个(N,M),输出所有可能的分配情况。

 

自己写了一个下,纯暴力,几乎没剪枝。

 

当n为20,m为10的时候,结果是40中情况。

 

codes:

/** * 假设 n>m 并且 n小于100 * @author Jason * 2011.3.30 */ public class Test { private int m; private int n; private int eggs[]; private int numAnswer; Test(){ m=10; n=20; numAnswer=0; eggs = new int[m]; for(int i=0;i<m;i++){ eggs[i]=0; } } private void fill(boolean [] state, int step, int sum){ if(step>=m){ state[sum] = true; return ; } fill(state,step+1,sum); fill(state,step+1,sum+eggs[step]); } /** * 判断是否满足:任意一个小于N的正整数,都能由某几个篮子内蛋的数量相加的和得到 * 算法:暴力枚举所有篮子的组合 * @return */ private boolean judge(){ boolean [] state = new boolean [n+1]; for(int i=0;i<=n;i++){ state[i] = false; } fill(state,0,0); for(int i=1;i<=n;i++){ if(!state[i]){ return false; } } return true; } /** * 给每个篮子分鸡蛋,升序(后一个篮子的鸡蛋必须不小于前一个篮子,避免重复计算) * @param pre 前一个篮子鸡蛋数 * @param already 前step个篮子 已使用的鸡蛋数 * @param step 第step个篮子 */ public void solve(int pre,int already, int step){ if(step==m-1){ //最后一个篮子 eggs[m-1]=n-already; //不符合条件 if(eggs[m-1]<pre) return; //判断是否满足:任意一个小于N的正整数,都能由某几个篮子内蛋的数量相加的和得到 if(judge()) { for(int i=0;i<m;i++){ System.out.print(eggs[i]+” “); } System.out.println(); numAnswer++; } return ; } // 给第step个篮子装鸡蛋,pre 到 n-already 种可能 for(int i=pre; i<=n-already; i++){ eggs[step]=i; //递归 solve(i,already+i,step+1); } } public static void main(String arg [] ){ Test test = new Test(); test.solve(1,0,0); System.out.println(“可能情况的数量:”+test.numAnswer); } }  

结果:

1 1 1 1 1 1 1 1 2 10 

1 1 1 1 1 1 1 1 3 9 

1 1 1 1 1 1 1 1 4 8 

1 1 1 1 1 1 1 1 5 7 

1 1 1 1 1 1 1 1 6 6 

1 1 1 1 1 1 1 2 2 9 

1 1 1 1 1 1 1 2 3 8 

1 1 1 1 1 1 1 2 4 7 

1 1 1 1 1 1 1 2 5 6 

1 1 1 1 1 1 1 3 3 7 

1 1 1 1 1 1 1 3 4 6 

1 1 1 1 1 1 1 3 5 5 

1 1 1 1 1 1 1 4 4 5 

1 1 1 1 1 1 2 2 2 8 

1 1 1 1 1 1 2 2 3 7 

1 1 1 1 1 1 2 2 4 6 

1 1 1 1 1 1 2 2 5 5 

1 1 1 1 1 1 2 3 3 6 

1 1 1 1 1 1 2 3 4 5 

1 1 1 1 1 1 2 4 4 4 

1 1 1 1 1 1 3 3 3 5 

1 1 1 1 1 1 3 3 4 4 

1 1 1 1 1 2 2 2 2 7 

1 1 1 1 1 2 2 2 3 6 

1 1 1 1 1 2 2 2 4 5 

1 1 1 1 1 2 2 3 3 5 

1 1 1 1 1 2 2 3 4 4 

1 1 1 1 1 2 3 3 3 4 

1 1 1 1 1 3 3 3 3 3 

1 1 1 1 2 2 2 2 2 6 

1 1 1 1 2 2 2 2 3 5 

1 1 1 1 2 2 2 2 4 4 

1 1 1 1 2 2 2 3 3 4 

1 1 1 1 2 2 3 3 3 3 

1 1 1 2 2 2 2 2 2 5 

1 1 1 2 2 2 2 2 3 4 

1 1 1 2 2 2 2 3 3 3 

1 1 2 2 2 2 2 2 2 4 

1 1 2 2 2 2 2 2 3 3 

1 2 2 2 2 2 2 2 2 3 

可能情况的数量:40

 

 

 

 

 

点赞