经典数学问题“空瓶换酒”:某啤酒店可用a(>0)个空啤酒瓶换b(<a)瓶啤酒,某人一次购买n瓶啤酒,问其最多能够喝多少瓶啤酒?

通常这类问题希望我们要“投机取巧”,即先找店家或他人借空瓶,换酒喝完后再如数归还

为求全面,本人分别对“允许借空瓶”与“不允许借空瓶”两种情况进行推导

(一)允许借空瓶:

能借到空瓶我们可以尽可能做到物尽其用

每换一次需要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)

程序界面如图:

               

程序主要代码如下:

#include "stdafx.h"
#include <Windows.h>
#include <Commctrl.h>
#pragma comment(lib, "Comctl32.lib")
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")#define INPUT_LIMIT    9static HWND hEditA;
static HWND hEditB;
static HWND hEditN;
static HWND hButtonCalc;
static HWND hEditRes1;
static HWND hEditRes2;
static HWND hEditRes3;static VOID ClearResults()
{if (!IsWindowEnabled(hButtonCalc)){SetWindowText(hEditRes1, TEXT(""));SetWindowText(hEditRes2, TEXT(""));SetWindowText(hEditRes3, TEXT(""));EnableWindow(hButtonCalc, TRUE);}
}INT_PTR CALLBACK DialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER(lParam);switch (uMsg){case WM_INITDIALOG:{HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON));SendMessage(hWndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);SendMessage(hWndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);hEditA = GetDlgItem(hWndDlg, IDC_EDIT_A);hEditB = GetDlgItem(hWndDlg, IDC_EDIT_B);hEditN = GetDlgItem(hWndDlg, IDC_EDIT_N);HWND hCheckBorrow = GetDlgItem(hWndDlg, IDC_CHECK_BORROW);hButtonCalc = GetDlgItem(hWndDlg, IDC_BUTTON_CALC);hEditRes1 = GetDlgItem(hWndDlg, IDC_EDIT_RES1);hEditRes2 = GetDlgItem(hWndDlg, IDC_EDIT_RES2);hEditRes3 = GetDlgItem(hWndDlg, IDC_EDIT_RES3);SetWindowText(hEditA, TEXT("3"));SendMessage(hEditA, EM_SETLIMITTEXT, (WPARAM)INPUT_LIMIT, (LPARAM)0);SetWindowText(hEditB, TEXT("1"));SendMessage(hEditB, EM_SETLIMITTEXT, (WPARAM)INPUT_LIMIT, (LPARAM)0);SetWindowText(hEditN, TEXT("18"));SendMessage(hEditN, EM_SETLIMITTEXT, (WPARAM)INPUT_LIMIT, (LPARAM)0);SendMessage(hCheckBorrow, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0);return (INT_PTR)TRUE;}break;case WM_COMMAND:{switch (wParam){case MAKEWPARAM(IDCANCEL, BN_CLICKED):{EndDialog(hWndDlg, (INT_PTR)0);return (INT_PTR)TRUE;}break;case MAKEWPARAM(IDC_EDIT_A, EN_CHANGE):{ClearResults();return (INT_PTR)TRUE;}break;case MAKEWPARAM(IDC_EDIT_B, EN_CHANGE):{ClearResults();return (INT_PTR)TRUE;}break;case MAKEWPARAM(IDC_EDIT_N, EN_CHANGE):{ClearResults();return (INT_PTR)TRUE;}break;case MAKEWPARAM(IDC_CHECK_BORROW, BN_CLICKED):{ClearResults();return (INT_PTR)TRUE;}break;case MAKEWPARAM(IDC_BUTTON_CALC, BN_CLICKED): //计算部分{if (GetWindowTextLength(hEditA) <= 0){MessageBox(hWndDlg, TEXT("未输入起换空瓶数(a)!"), TEXT("错误"), MB_OK | MB_ICONHAND);SetFocus(hEditA);return (INT_PTR)TRUE;}if (GetWindowTextLength(hEditB) <= 0){MessageBox(hWndDlg, TEXT("未输入可换啤酒数(b)!"), TEXT("错误"), MB_OK | MB_ICONHAND);SetFocus(hEditB);return (INT_PTR)TRUE;}if (GetWindowTextLength(hEditN) <= 0){MessageBox(hWndDlg, TEXT("未输入购买啤酒数(n)!"), TEXT("错误"), MB_OK | MB_ICONHAND);SetFocus(hEditN);return (INT_PTR)TRUE;}UINT a = GetDlgItemInt(hWndDlg, IDC_EDIT_A, NULL, FALSE);if (!a){MessageBox(hWndDlg, TEXT("起换空瓶数(a)应大于0!"), TEXT("错误"), MB_OK | MB_ICONHAND);SendMessage(hEditA, EM_SETSEL, (WPARAM)0, (LPARAM)-1);SetFocus(hEditA);return (INT_PTR)TRUE;}UINT b = GetDlgItemInt(hWndDlg, IDC_EDIT_B, NULL, FALSE);if (b >= a){MessageBox(hWndDlg, TEXT("可换啤酒数(b)应小于起换空瓶数(a)!"), TEXT("错误"), MB_OK | MB_ICONHAND);SendMessage(hEditB, EM_SETSEL, (WPARAM)0, (LPARAM)-1);SetFocus(hEditB);return (INT_PTR)TRUE;}UINT n = GetDlgItemInt(hWndDlg, IDC_EDIT_N, NULL, FALSE);UINT u1, u2, u3;if (IsDlgButtonChecked(hWndDlg, IDC_CHECK_BORROW) == BST_UNCHECKED){if (n < b)b = n;u1 = (n - b) / (a - b);u2 = (n - b) % (a - b);u3 = b;}else{u1 = n / (a - b);u2 = n % (a - b);u3 = 0U;}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()
{{INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = (DWORD)sizeof(INITCOMMONCONTROLSEX);InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);}ExitProcess((UINT)DialogBoxParam(NULL, MAKEINTRESOURCE(IDD_DIALOG), NULL, DialogProc, (LPARAM)0));
}

完整的代码及程序下载:点击打开链接

结论

1、将“空瓶换酒”问题公式化,分别推导了“允许借空瓶”与“不允许借空瓶”两种情况计算公式

2、根据推导的计算公式开发了计算“空瓶换酒”问题的程序,比使用循环方式计算的程序简洁且高效

3、通过推导与观察可发现,购买n瓶啤酒大约可以喝到a/(a-b)*n瓶,也就是约为购买数量的a/(a-b)倍(注:这里不再是整数除法),且a越大或a与b越接近时此倍数越大。即使按常见的3:1比例兑换,买668瓶就能喝到1000瓶,一般人是该满意了哈~

经典数学问题“空瓶换酒”求解(C/C++)相关推荐

  1. Python3多思路解决空瓶换酒问题

    思路导航 前言 一.一行代码 二.迭代求解 三.递归求解 总结 前言   空瓶换酒是一类很经典的智力趣题,也有很多不同的问题版本.本文旨在小结其解决方法,以加深理解.   空瓶换酒的目标是求解最终能喝 ...

  2. 酒瓶换酒编程C语言,巧用公式速解“空瓶换酒”问题

    近年来,公务员考试数学运算部分出题形式越来越灵活,题型方面以极值问题.统筹问题.空瓶换酒等问题为代表.下面广西公务员考试网重点讲解一下"空瓶换酒"的解法. [真题精选]12个啤酒空 ...

  3. Python入门:从空瓶换酒聊起

    Python入门:从空瓶换酒聊起 最近在学习Python的过程中,发现了一道有趣的编程题目--空瓶换酒.这个问题是这样描述的:假设你有m个空瓶子,可以用其中n个空瓶子换一瓶酒.那么,你最终最多能喝到多 ...

  4. 空瓶换酒问题【一行代码】

    [问题] 已知:N个空瓶可以换 1 瓶酒, 问:若小明买m瓶,那么他最终可以喝到几瓶? [声明] N为大于 1 的自然数,否则结果为无穷. 不考虑借空瓶的行为. 空瓶换酒问题简单易懂,可以算是学习编程 ...

  5. 【算法基础】空瓶换酒

    文章目录 空瓶换酒-python实现 1.算法分析 1.1 通常情况 1.2 赊账情况 空瓶换酒-python实现 最近学习学习到一种空瓶换酒的算法,其题目描述为:假设一瓶啤酒2元钱,商家为了促销,规 ...

  6. java编写换酒问题,空瓶换酒问题

    例:某商店出售啤酒,规定每5个空啤酒瓶能换1瓶啤酒.张叔叔家买了80瓶啤酒,喝完后再按规定用空啤酒瓶去换啤酒,那么他们家前后共能喝到多少瓶啤酒? 分析与解:我们按照实际换酒过程分析: 喝掉80瓶啤酒, ...

  7. java编写换酒问题,ASP空瓶换酒递归算法题目

    今天有个朋友问我一个小学生的奥数题,酒1元钱1瓶,2个空瓶子可以换一瓶酒,问20块钱可以喝多少瓶酒.我OUT了,我被鄙视了. 我不会,但是谁让我是写代码的呢,写了个小程序用来鄙视他.告诉他,我不仅知道 ...

  8. #1518空瓶换酒问题

    一.题目 难度:简单 小区便利店正在促销,用 numExchange 个空酒瓶可以兑换一瓶新酒.你购入了 numBottles 瓶酒. 如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的. 请你计算 最多 能 ...

  9. python巧妙解决空瓶换酒问题

    问题: 某超市促销,举办空酒瓶和酒瓶盖换酒活动,规定 2 个空瓶或 4 个瓶盖可换一瓶酒.若小明最开始买了 n 瓶酒,则他总共能喝到多少瓶酒? 思路: 如果瓶子数大于2或盖子数大于4就可以换一瓶酒,而 ...

最新文章

  1. OpsDev是什么?
  2. 用bash命令得到Windows一个目录下的所有文件并且把结果输入到一个文件
  3. 华为认证数通专家HCIE-Datacom 11月30日发布
  4. java commons.util_Java — CommonUtil
  5. 昇腾AI计算,无惧618冲动消费
  6. oracle 9i手动启动数据库,Oracle9iAS (之五): 手工起动,关闭系统
  7. javaSE-基础篇-经典赋值:两变量值的交换
  8. 解决hibernate只能插入一条数据的问题
  9. Mysql ORDER BY用法的一点理解
  10. C语言水平镜像处理16色位图,C语言使用HZK16显示每个像素的代码
  11. 集成电路那些事儿:CMOS模拟集成电路版图基础
  12. Mac OS 下的Vim使用系统剪切板
  13. 图像质量评估指标(3) 特征相似度FSIM
  14. Android系统之制作开机LOGO
  15. VHDL——含异步清零和同步使能的加法计数器源程序
  16. c语言扇形打印图片,圆形CD绘制 (扇形)
  17. #发现你#小说的交互——交互故事性
  18. 子矩阵的和(Python实现)
  19. 编程语言之时下潮流与实用价值
  20. 图片如何添加水印文字?如何设置照片水印?

热门文章

  1. 虚拟大钢琴 – Steinberg The Grand 3 v3.2.0.146 WiN
  2. 微信 Mac 版 3.1.0 内测:支持发表朋友圈、浏览朋友圈相册
  3. 全国城市IP库-提供下载
  4. bzoj 3091 城市旅行
  5. BI数据分析软件有哪些?为什么说奥威BI很特别?
  6. 欢迎进入我的个人博客 anzhan.me
  7. pythonDDOS攻击
  8. 制作后台网站管理系统
  9. 单点登录和第三方登录
  10. 扩张受阻,驴妈妈、赞那度、遨游定制们该如何突围?