一道面試題 四人喝酒的問題

2021-06-01 23:49:10 字數 2855 閱讀 6973

有a,b,c,d四個人,現在有x,y,z三個不規則酒杯,x,y容量為8兩,現在已裝滿酒,z容量為3兩,為空杯.現在要求四個人每人都能平均喝到4兩酒,請說出該怎麼喝?寫出演算法,並列印出每步x,y,z杯內的酒多少和四個人每人所喝的酒?

這道題的**不可考。在網上搜《程式設計之美》烙餅問題的相關資料的時候看到了這道題,之前沒接觸過演算法,手算想了一會兒居然沒有算出來~

此題類似於《程式設計之美》中烙餅問題所採用的剪枝+分支定界,關鍵是對問題過程的處理。只要把問題過程理清,找好邊界條件和退出條件,問題自然迎刃而解。我們先找邊界條件,顯然

a)每個人都喝到4兩酒肯定是程式執行完成的條件,

b)為了避免重複進入之前某種狀態,我們需要判斷當前狀態是否出現過。

再明確我們倒酒的過程,這裡只需要弄清可以倒酒的狀態分類。首先,對x、y、z三個酒杯的狀態和a、b、c、d四個人喝酒的狀態要區別對待:

a)當且僅當某人當前的酒量和酒杯中酒量之和小於等於4,此人才能喝酒。顯然,這才是最終可以滿足邊界條件a的過程

b)在三個酒杯之間互相倒酒,要注意每個酒杯都不能溢位

c)如果此狀態之前出現過,說明這種狀態之下走不通,就沒有必要在此狀態之下繼續進行。另外,x和y酒杯由於容量一樣,在其他狀態相同的情況下,可視為相同的狀態。

理解了這些,寫出**就比較容易。

/* 有a,b,c,d四個人,現在有x,y,z三個不規則酒杯,x,y容量為8兩,現在已裝滿酒,

* z容量為3兩,為空杯.現在要求四個人每人都能平均喝到4兩酒,請說出該怎麼喝?

* 寫出演算法,並列印出每步x,y,z杯內的酒多少和四個人每人所喝的酒?

*/#include /* 遞迴呼叫退出條件:每人都喝到4兩,或者回到中間的某個狀態 */

#define max_states 1024 /* 儲存中間狀態,如果是之前的某個狀態就退出 */

#define max_steps 100 /* 儲存最終採用的步驟 */

typedef struct

state;

static int stateindex;

static int pourstepstate[max_states]; /* 類似於棧結構,中間狀態 */

static int maxsteps;

static state printstepindex[max_steps]; /* 最終採用的狀態 */

static __inline void printpoursteps(state tempstate)

}#define state_exist 1

#define state_not_exist 0

static int checkstate(state tempstate)

for(i = stateindex; i > 0; i--) }

pourstepstate[++stateindex] = tempsum;

return state_not_exist;

}static __inline void pourstepnext(state *tempstate, state *prestate)

return;

}#define pour_succeed 1

#define pour_fail 0

/* 分清處理步驟,注意順序先嘗試x,y,z向a,b,c,d中倒,然後進行

* x,y,z之間的處理,否則容易出現死迴圈或者中間過程過度展開

*/int dopouring(state prestate)

if(checkstate(tempstate) == state_not_exist)}}

} }if(prestate.statearray[1] < 8 && prestate.statearray[0]) /* x --> y */

else

if(checkstate(tempstate) == state_not_exist)

}} if(prestate.statearray[2] < 3 && prestate.statearray[0]) /* x --> z */

else

if(checkstate(tempstate) == state_not_exist)

}} if(prestate.statearray[0] < 8 && prestate.statearray[1]) /* y --> x */

else

if(checkstate(tempstate) == state_not_exist)

}} if(prestate.statearray[2] < 3 && prestate.statearray[1]) /* y --> z */

else

if(checkstate(tempstate) == state_not_exist)

}} if(prestate.statearray[0] < 8 && prestate.statearray[2]) /* z --> x */

else

if(checkstate(tempstate) == state_not_exist)

}} if(prestate.statearray[1] < 8 && prestate.statearray[2]) /* z --> y */

else

if(checkstate(tempstate) == state_not_exist)

}} return pour_fail;

}int main()

printf("\n");

for(i = maxsteps; i > 0; i--)

printf("total steps: %d.\ndone.\n", maxsteps);

return 0;

}

一道面試題

一道面試題 射擊運動員10發打中90環有多少種可能,請編寫程式計算出來,並列印出結果,0環和10環均有效。打中90環就是沒打中10環,所以打中90環跟打中10環的可能性是一樣的。然後開始遞迴狂打槍,一到10就記錄 if params i 10 在迴圈的控制中已經排除了大於10的可能性 i 10 pa...

一道面試題

前些時候在找工作,就在準備結束此次找工作歷程的時候,去了一家公司面試,去了之後技術經理直接帶到一台電腦旁,給了一張紙條,上面是這樣的題目 用c或c 來實現 1 建立一棵樹,該樹的深度是隨機的,每個節點的位元組點數是隨機的。2 給每個節點分配一段隨機大小的記憶體空間,給每個節點賦乙個隨機數。3 遍歷這...

一道面試題

如果n為偶數,則將它除以2,如果n為奇數,則將它加1或者減1。問對於乙個給定的n,怎樣才能用最少的步驟將它變到1。例如 n 61 n 60 n 2 30 n 2 15 n 16 n 2 8 n 2 4 n 2 2 n 2 1 public class myclass public static vo...