【你问我答】老大爷卖酒,如何用4个容器分出2斤酒?

问题描述:

一位卖酒的老大爷有两个各装满了20斤白酒的酒桶。一天,来了两个顾客,分别带着一个可以装5斤酒的瓶子和一个可以装4斤酒的瓶子。只用这四个容器,如何给他们的瓶子里各倒2斤酒?

回答有奖:

选取一位认真回答问题的牛友,赠送200牛币!
▶回答尽量有自己的思考,不要单纯的只是复制粘贴定理定义,或者他人blog哦~

你问我答问题汇总:点击进入
关注你问我答栏目:点击关注

你问我答 - 答问题,成大佬,拿牛币!
你问我答是牛客新栏目,每周1期几个问题,
牛友在问题贴下留下自己的知识,经验与见解,
帮助更多牛友了解更多技术相关知识!
#悬赏#
全部评论
我用(a,b,c,d) 四个数表示刚开始老大爷的两个桶,以及两个顾客的5斤酒和4斤酒的桶中酒的重量,其实就是 bfs 跑一边几个桶的酒相互到,具体的流程是下面: (20,20,0,0)  (20,15,5,0) (20,15,1,4) (20,19,1,0) (20,19,0,1) (20,14,5,1) (20,14,2,4) (20,18,2,0)   (16,18,2,4)   (16,20,2,2)
11 回复
分享
发布于 2019-11-05 11:34
将装有20斤酒的两个桶称为桶a和桶b,首先桶a倒出酒装满5斤瓶,5斤瓶的酒倒入4斤瓶装满,则5斤瓶还剩下1斤,这时候将4斤瓶的酒全部倒回桶a,再把5斤瓶的1斤酒全部倒入4斤瓶,再从桶a倒出酒装满5斤瓶,然后5斤瓶的酒倒出装满4斤瓶,由于4斤瓶原来还有1斤,所以这时候5斤瓶只倒出了3斤,5斤瓶中还剩余2斤。再将4斤瓶中的酒全部倒入桶a,则桶a中有18斤酒,再将桶b中的酒倒满4斤瓶,然后4斤瓶中的酒倒入桶a,由于桶a原来有18斤,所以这次倒入了2斤,4斤瓶中还剩余2斤酒,此时4斤瓶和5斤瓶合有2斤酒
5 回复
分享
发布于 2019-11-05 11:40
阅文集团
校招火热招聘中
官网直投
二楼的回答很棒,很清晰. 应该还有一个很浪费的方法: 5斤+4斤 = 9斤(这是在题意下能得到的确定容量) 也就是说酒桶(20斤)只要把两瓶倒满,清空瓶,再倒满,就完成了20-9-9 = 2斤的操作 另一个酒桶重复一次,也是剩下2斤 那么就可以清空酒瓶,分别两个酒桶剩下的2斤酒倒进瓶了... 袁爷爷:你就是吃太饱了!!!
2 回复
分享
发布于 2019-11-05 11:51
20,20,0,0 11,20,4,5 倒了 11,20,0,0 2,20,4,5 倒了 2,20,0,0 ... 2,2,0,0
2 回复
分享
发布于 2019-11-05 16:00
假设所有桶都已经消毒完毕,不存在交叉污染,每次倒转桶内残留忽略不计。 20斤桶先将5斤桶倒满(20斤桶剩余15斤),然后5斤桶将4斤桶倒满(5斤桶剩余1斤),然后将4斤桶全部倒回20斤桶(20斤桶剩余19斤),再将5斤桶里的1斤倒至4斤桶中,然后用20斤桶将5斤桶再倒满(20斤桶剩余14斤),再用5斤桶将4斤桶装满(5斤桶剩余2斤),至此5斤桶结束;然后将4斤桶全部倒回至20斤桶中(20斤桶剩余18斤),然后用另一个20斤桶将4斤桶装满(20斤桶剩余16斤),再用4斤桶将剩有18斤的20斤桶装满(4斤桶剩余2斤),至此4斤桶也结束。
1 回复
分享
发布于 2019-11-05 11:46
20,20,0,0 16,20,0,4 16,20,4,0 12,20,4,4 12,20,5,3 17,20,0,3 17,20,3,0 13,20,3,4 13,20,5,2 18,20,0,2 18,20,2,0, 18,16,2,4 20,16,2,2
1 回复
分享
发布于 2019-11-05 11:56
第一个桶倒到5,5倒到4,4倒回第一个桶,5又倒到4,第一个桶倒到5,5倒到4,4倒回第一个桶,此时相当于第一个桶倒了2进5,然后第二个桶倒4,4倒第一个桶,就有2 2了
1 回复
分享
发布于 2019-11-05 14:32
看不到我,看不到我~~~ 运行截图: 代码: #include <iostream> #include <bits/stdc++.h> using namespace std; int step[10][10][5][6];//每个20斤酒桶最多倒出9斤,所以剩下11斤无用,状态就是0~9,所以共有10×10×4×5 = 2000种状态 int full[4] = {9,9,4,5}; //满状态 bool finish; struct now {     int barrel[4]; }; stack<struct now> que; stack<struct now> sta; void dfs(struct now now_step)//dfs {     struct now next_step;     if(finish == true)         return;     sta.push(now_step);     if(now_step.barrel[2] == 2 && now_step.barrel[3] == 2)//找到     {         step[now_step.barrel[0]][now_step.barrel[1]][now_step.barrel[2]][now_step.barrel[3]] = 1;         finish = true;         return;     }     for(int i = 0;i < 4; i++)//所有情况     {         for(int j = 0;j < 4;j++)         {             if(i == j)                 continue;             next_step.barrel[0] = now_step.barrel[0];             next_step.barrel[1] = now_step.barrel[1];             next_step.barrel[2] = now_step.barrel[2];             next_step.barrel[3] = now_step.barrel[3];             if(now_step.barrel[i] + now_step.barrel[j] >= full[i])             {                 next_step.barrel[i] = full[i];                 next_step.barrel[j] = now_step.barrel[i] + now_step.barrel[j] - full[i];             }             else             {                 next_step.barrel[i] = now_step.barrel[i] + now_step.barrel[j];                 next_step.barrel[j] = 0;             }             if(step[next_step.barrel[0]][next_step.barrel[1]][next_step.barrel[2]][next_step.barrel[3]] == 0)//剪枝             {                 step[next_step.barrel[0]][next_step.barrel[1]][next_step.barrel[2]][next_step.barrel[3]] = 1;                 step[next_step.barrel[1]][next_step.barrel[0]][next_step.barrel[2]][next_step.barrel[3]] = 1;                 dfs(next_step);             }         }     }     if(finish == false)//清栈         sta.pop(); } int main() {     struct now start;     int foot = 0;     start.barrel[0] = 9;     start.barrel[1] = 9;     start.barrel[2] = 0;     start.barrel[3] = 0;     for(int i =0 ;i < 10;i++)         for(int j =0 ;j < 10;j++)             for(int k =0 ;k < 5;k++)                 for(int l =0 ;l < 6;l++)                     step[i][j][k][l] = 0;     step[9][9][0][0] = 1;     finish = false;     dfs(start);     while(!sta.empty())     {         que.push(sta.top());         sta.pop();     }     printf("          桶1  桶2  桶3  桶4 \n");     while(!que.empty())     {         if(foot == 0)             printf("初  始:  ");         else             printf("第%2d步:  ",foot);         printf("  %d    %d    %d    %d\n",que.top().barrel[0] + 11,que.top().barrel[1] + 11 ,que.top().barrel[2],que.top().barrel[3]);         foot++;         que.pop();     }     return 0; }
1 回复
分享
发布于 2019-11-06 09:27
第一个桶20-6-6-6,最后剩下两斤;第二个桶20-3-3-3-3-3-3,同样剩下两斤。两个桶里剩下的倒入两个容器 。是不是有点浪费酒啊#%*!
点赞 回复
分享
发布于 2019-11-05 11:33
利用20 20 5 4 凑出两个2斤出来 第一个2  先倒满5,5往4里面倒,5中就剩下了1,重复此步得到2,就有了第一个两斤 第二个2 5斤的桶里有2,4斤桶里有,剩下两个大桶里就是20,18,也能比差值做出第二个2
点赞 回复
分享
发布于 2019-11-05 18:05
点赞 回复
分享
发布于 2019-11-05 18:47
哈哈,才看到,晚了一步
点赞 回复
分享
发布于 2019-11-05 18:49
分析一下。首先木桶2个20斤酒肯定是够的,我们的容器是20 20 4 5。然后酒瓶是4和5,那么直观的就可以得到差值为1的酒量5+0-4=1,即神装酒瓶5向裸装酒瓶4倒酒剩1斤,最终得到这个1斤记为步骤1。现在我们有5 4 1三个数,直观的就有5+1-4=2,即容量5的满酒瓶倒向装有1斤酒的酒瓶4,酒瓶5里剩2斤,这一步记为步骤2。步骤2得到2之后,2放哪个酒瓶只不过来回倒一下就可以,我们必有一个桶是18。18 4 20可以组合出4+18-20=2,即容量4的酒向18的桶倒装20后剩2。此时有两个2,记为步骤3。接下来完善每一步就行了,步骤1,先倒满5,5去倒4剩1。4的酒倒回桶里,此时有20 19 0 1(5)。步骤2:1斤的酒从瓶5倒瓶4,然后从木桶倒满5,注意木桶最好选用不同的桶这样能得到更差异化的容量,因为两个木桶可以互相匀,可以回退出某个木桶是满的,但此题这样做还要匀回去,多走一步。5倒向4,由于4有容量1的酒了,所以此时结果是20 14 4 2(5)或者 15 19 4 2(5),15 19可以匀出20 14。步骤3,把酒瓶4的酒倒回酒桶,得到20 18 0(4) 2。4+18-20=2,所以20倒给空酒瓶4,酒瓶4倒向酒桶18,这时候酒瓶4剩2,此时酒瓶5也是2,就硬凑出来答案了。
点赞 回复
分享
发布于 2019-11-11 11:00

相关推荐

1 2 评论
分享
牛客网
牛客企业服务