經典數學問題「空瓶換酒」:某啤酒店可用a(>0)個空啤酒瓶換b(
通常這類問題希望我們要「投機取巧」,即先找店家或他人借空瓶,換酒喝完後再如數歸還
為求全面,本人分別對「允許借空瓶」與「不允許借空瓶」兩種情況進行推導
(一)允許借空瓶:
能借到空瓶我們可以盡可能做到物盡其用
每換一次需要a個空瓶,而換來的酒喝完後又有b個空瓶,實際每次兌換空瓶減少(a-b)個
於是n個空瓶總共可兌換:n/(a-b) 次(式中除法為整數除法,商為兌換次數,餘數則是最後剩餘的空瓶數)
由於每次兌換可得到b瓶啤酒,於是共可兌換n/(a-b)*b瓶啤酒
一共能喝到的啤酒數當然也就為(n + n/(a-b)*b)瓶了
(二)不允許借空瓶
如果沒人願意借給你空瓶,此時只能「自力更生」了
若n小於a,很明顯一次也兌換不了,一共能喝的也就是買的那n瓶啤酒
若n不小於a,一旦剩餘空瓶數小於a,則兌換結束
為方便計算,預留a個空瓶,先兌換其餘(n-a)個空瓶,於是可從預留的a個空瓶裡去「借」,喝完再「歸還」
根據「允許借空瓶」情況公式,(n-a)個空瓶總共可兌換:(n-a)/(a-b) 次(同上,式中除法表示整數除法)
由於預留的a個空瓶最後還可再進行一次兌換,故總兌換總次數為:(n-a)/(a-b)+1,化簡後為(n-b)/(a-b) 次
最後預留的a個空瓶換的b瓶啤酒喝完後還會得到b個空瓶,故最後剩餘的空瓶數為上式餘數加b
由於每次兌換可得到b瓶啤酒,於是共可兌換(n-b)/(a-b)*b瓶啤酒
一共能喝到的啤酒數當然也就為(n + (n-b)/(a-b)*b)瓶了
為將以上公式通用化,當n小於b時,b取值同n
基於上述推導,本人開發了求解「空瓶換酒」問題的win32應用程式,開發語言c/c++(結合windows sdk)
程式介面如圖:
程式主要**如下:
結論1、將「空瓶換酒」問題公式化,分別推導了「允許借空瓶」與「不允許借空瓶」兩種情況計算公式#include "stdafx.h"
#include #include #pragma comment(lib, "comctl32.lib")
#include #pragma comment(lib, "shlwapi.lib")
#define input_limit 9
static hwnd hedita;
static hwnd heditb;
static hwnd heditn;
static hwnd hbuttoncalc;
static hwnd heditres1;
static hwnd heditres2;
static hwnd heditres3;
static void clearresults()
}int_ptr callback dialogproc(hwnd hwnddlg, uint umsg, wparam wparam, lparam lparam)
break;
case wm_command:
break;
case makewparam(idc_edit_a, en_change):
break;
case makewparam(idc_edit_b, en_change):
break;
case makewparam(idc_edit_n, en_change):
break;
case makewparam(idc_check_borrow, bn_clicked):
break;
case makewparam(idc_button_calc, bn_clicked): //計算部分
if (getwindowtextlength(heditb) <= 0)
if (getwindowtextlength(heditn) <= 0)
uint a = getdlgitemint(hwnddlg, idc_edit_a, null, false);
if (!a)
uint b = getdlgitemint(hwnddlg, idc_edit_b, null, false);
if (b >= a)
uint n = getdlgitemint(hwnddlg, idc_edit_n, null, false);
uint u1, u2, u3;
if (isdlgbuttonchecked(hwnddlg, idc_check_borrow) == bst_unchecked)
else
tchar sztext[12];
wnsprintf(sztext, 12, text("%u"), u1);
setwindowtext(heditres1, sztext);
wnsprintf(sztext, 12, text("%u"), u2 + u3);
setwindowtext(heditres2, sztext);
wnsprintf(sztext, 12, text("%u"), n + u1 * b);
setwindowtext(heditres3, sztext);
enablewindow(hbuttoncalc, false);
return (int_ptr)true;
} break;
} }break;
} return (int_ptr)false;
}extern "c" void startup()
exitprocess((uint)dialogboxparam(null, makeintresource(idd_dialog), null, dialogproc, (lparam)0));
}
2、根據推導的計算公式開發了計算「空瓶換酒」問題的程式,比使用迴圈方式計算的程式簡潔且高效
3、通過推導與觀察可發現,購買n瓶啤酒大約可以喝到a/(a-b)*n瓶,也就是約為購買數量的a/(a-b)倍(注:這裡不再是整數除法),且a越大或a與b越接近時此倍數越大。即使按常見的3:1比例兌換,買668瓶就能喝到1000瓶,一般人是該滿意了哈~
海盜分酒(數學問題)
海盜分酒 題目描述 有一群海盜 不多於 20人 在船上比拼酒量。過程如下 開啟一瓶酒,所有在場的人平分喝下,有幾個人倒下了。再開啟一瓶酒平分,又有倒下的,再次重複 直到開了第 4瓶酒,坐著的已經所剩無幾,海盜船長也在其中。當第 4瓶酒平分喝下後,大家都倒下了。等船長醒來,發現海盜船擱淺了。他在航海日...
經典數學問題 Nim遊戲
nim遊戲是博弈論中最經典的模型,是組合遊戲 combinatorial games 的一種,屬於 impartial combinatorial games 以下簡稱icg 滿足以下條件的遊戲是icg 1 有兩名選手 2 兩名選手交替對遊戲進行移動 move 每次一步,選手可以在 一般而言 有限的...
經典數學問題 Nim遊戲
nim遊戲是博弈論中最經典的模型,是組合遊戲 combinatorial games 的一種,屬於 impartial combinatorial games 以下簡稱icg 滿足以下條件的遊戲是icg 1 有兩名選手 2 兩名選手交替對遊戲進行移動 move 每次一步,選手可以在 一般而言 有限的...