程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 雞蛋籃子算法題

雞蛋籃子算法題

編輯:C++入門知識

題目:把N個雞蛋放到M個籃子裡,每個籃子不能為空,要求滿足:任意給出一個不超過N的數量,都能找到其中某幾個籃子的雞蛋和等於它。
請寫一個程序,輸入N,M,然後輸出所有的雞蛋放法。
題目解釋:例如6個雞蛋放3個籃子的一種可能為1,2,3,任意給出1<=x<=6的值,都可以找到1,2,3中的組合的和等於x.

該題目最早是我在網上看到一道600個雞蛋放在10個籃子的放法,答案是給出了一個按2的乘積放的特例。我將其改編後用來招聘時考察工程師上機編程技能。

解題思路如下:
假設第一個籃子放一個雞蛋:
那麼1,X2中,X2可以放雞蛋的范圍是1<= X2<=2, 如果X2=3,便滿足不了給出n=2的情況了
取X2=2
那麼1,2,X3中,X3可以放雞蛋的范圍是2<= X3<=4
......
可以推出數學公式:在前m個籃子滿足要求時,第m+1個籃子可以放置的雞蛋數范圍應該是: Xm<=Xm+1<=N+1
該范圍同時也是搜索解的空間,比較好用遞歸實現,對於每找到一個符合范圍的Xm,可以進一步深度遍歷尋找下一個Xm+1, 由此便容易理解標准答案的實現了。

如果使用蠻力計算出所有組合,再逐一過濾篩選也可以實現,但是程序肯定要比上面繁瑣,效率較低。

希望通過該題目能篩選到編程上有天賦的學生,特別是能獨立完成構思和代碼編寫的,應該是很有潛力的。只是該類型的題目並不是特別適合筆試,很多學生寫了大段代碼邏輯難以判斷是否能正確輸出,筆試只適合考基礎知識,進一步可安排其上機檢查其程序技能。

按照以上的思路,寫了一下代碼。

[cpp]
#include <iostream>  
#include <vector>  
using namespace std; 
 
void eggProblem(int N, int M, int& count, int sum, int i, vector<int>& vec) 

    if (i == M) 
    { 
        if (sum == N) 
        { 
            count++; 
            cout<<"The "<<count<<" way: "; 
            vector<int>::iterator it; 
            for (it = vec.begin(); it != vec.end(); it++) 
            { 
                cout<<*it<<" "; 
            } 
            cout<<endl; 
            return; 
        } 
        else 
            return; 
    } 
 
    if (i == M-1 && N-sum > sum+1) 
    { 
        if ((N-sum > sum+1)||(N-sum)<vec.back())  //對倒數第二個次進行剪枝。  
        { 
            return; 
        } 
 
    } 
 
    if (i == 0) 
    { 
        vec.push_back(1); 
        count=0; 
        sum=1; 
        i++; 
    } 
    if (!vec.empty()) 
    { 
        int temp = vec.back(); 
        for (int j = temp; j <= sum+1; j++) 
        { 
            i++; 
            sum += j; 
            vec.push_back(j); 
            eggProblem(N, M, count, sum, i, vec); 
            i--; 
            sum -= j; 
            vec.pop_back(); 
        } 
    } 
 

 
int main() 

    int N = 20, M = 6; 
    int count, sum; 
    vector<int> vec; 
    eggProblem(N, M, count, sum, 0, vec);    
    if (count == 0) 
    { 
        cout<<"sorry we cannot find.."<<endl; 
    } 

#include <iostream>
#include <vector>
using namespace std;

void eggProblem(int N, int M, int& count, int sum, int i, vector<int>& vec)
{
 if (i == M)
 {
  if (sum == N)
  {
   count++;
   cout<<"The "<<count<<" way: ";
   vector<int>::iterator it;
   for (it = vec.begin(); it != vec.end(); it++)
   {
    cout<<*it<<" ";
   }
   cout<<endl;
   return;
  }
  else
   return;
 }

 if (i == M-1 && N-sum > sum+1)
 {
  if ((N-sum > sum+1)||(N-sum)<vec.back()) //對倒數第二個次進行剪枝。
  {
   return;
  }

 }

 if (i == 0)
 {
  vec.push_back(1);
  count=0;
  sum=1;
  i++;
 }
 if (!vec.empty())
 {
  int temp = vec.back();
  for (int j = temp; j <= sum+1; j++)
  {
   i++;
   sum += j;
   vec.push_back(j);
   eggProblem(N, M, count, sum, i, vec);
   i--;
   sum -= j;
   vec.pop_back();
  }
 }

}

int main()
{
 int N = 20, M = 6;
 int count, sum;
 vector<int> vec;
 eggProblem(N, M, count, sum, 0, vec); 
 if (count == 0)
 {
  cout<<"sorry we cannot find.."<<endl;
 }
}
 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved