比酒量問題與二叉樹搜尋和路徑問題

鴨脖發表於2012-11-29

比酒量問題:

有一群海盜(不多於20人),在船上比拼酒量。過程如下:開啟一瓶酒,所有在場的人平分喝下,有幾個人倒下了。再開啟一瓶酒平分,又有倒下的,再次重複...... 直到開了第4瓶酒,坐著的已經所剩無幾,海盜船長也在其中。當第4瓶酒平分喝下後,大家都倒下了。


等船長醒來,發現海盜船擱淺了。他在航海日誌中寫到:“......昨天,我正好喝了一瓶.......奉勸大家,開船不喝酒,喝酒別開船......”

請你根據這些資訊,推斷開始有多少人,每一輪喝下來還剩多少人。

如果有多個可能的答案,請列出所有答案,每個答案佔一行。


剛開始我的想法是這樣的:

構造20棵樹,樹根的值分別是1,2,.......,20.然後搜尋路徑使得路徑上的和是20!。但是我發現這樣是行不通的,因為20!已經溢位,不管是long還是int。而且最後我發現我小題大作了。因為這道題無非就是一個多項式窮舉的問題,就是利用窮舉法求方程1/a+1/b+1/c+1/d = 1的所有解。直接通分一下,也就是bcd+acd+abd+abc=abcd。其中20>=a>=b>=c>=d>=1.所以這道題歸根結底是一道數學題而不是程式設計題。用四個for迴圈便可以求得其解:


#include<iostream>
using namespace std;


int maxN = 20;
int a;
int b;
int c;
int d;
int count = 0;


int main(){
for(a=1;a<=maxN;a++){
for(b=1;b<=a;b++){
for(c=1;c<=b;c++){
for(d=1;d<=c;d++){
count++;
if(b*c*d+a*c*d+a*b*c+a*b*d== a*b*c*d)
cout<<a<<"\t"<<b<<"\t"<<c<<"\t"<<d<<endl;
}
}
}
}
cout<<endl<<count<<endl;
}


====================================================================

在這也貼一段用遞迴尋找特定和的二叉樹路徑的演算法,自己寫的:

int sum(int count,int* x){
int tmp = 0;
for(int i=0;i<=count;i++){
tmp += x[i];
}
return tmp;
}


bool Place(int count,int* x,int des,BinaryTreeNode* t){
if(t->m_nValue + sum(count,x) > des)
return false;
return true;
}


void FindPath(int count,int* x,int des,BinaryTreeNode* t){
if(Place(count,x,des,t)){
count++;
x[count] = t->m_nValue;
if(t->m_pLeft == NULL && t->m_pRight == NULL){
if(sum(count,x) == des){
for(int i=0;i<=count;i++)
cout<<x[i]<<" ";
cout<<endl;
}
}else{
if(t->m_pLeft != NULL)
FindPath(count,x,des,t->m_pLeft);
if(t->m_pRight != NULL)
FindPath(count,x,des,t->m_pRight);
}
}
}




相關文章