醉汉平均分酒的问题!据说曾经是微软的面试题

失落夏天
Android领域优质创作者
博客专家认证
2012-11-18 04:59:51
有三个酒杯,形状都不规则,分别能装8,8,3升酒。
其中两个8升的杯子里面装满了酒。
现在有四个人要分酒,一个人分4升酒,应该怎么分?
用算法来实现这个功能应该怎么实现?
java,c++都可以。
...全文
459 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
nash142857 2012-11-28
  • 打赏
  • 举报
回复
BFS就行了吧、、
JackBurd 2012-11-22
  • 打赏
  • 举报
回复
这不就是波瓦松分酒的变式吗?广度搜索就可以了。
qjgdftxmu 2012-11-21
  • 打赏
  • 举报
回复
引用 1 楼 sxcong 的回复:
题目不完整吧,4个人分,怎么也要4个杯子才行。只有3个杯子,要两人用一个杯子,再醉的人也受不了。
每个人手上有杯子,那个8,8,3只是容器
mathe 2012-11-21
  • 打赏
  • 举报
回复
提供一个C++版本的:
#include <map>
#include <list>
#include <iostream>
using namespace std;
#define NUM_CUPS 3
#define NUM_MEN  4
#define P 11
#define HASH_SIZE 10007
struct State{
	char cup[NUM_CUPS];
	char man[NUM_MEN];
public:
	bool operator<(const State& s)const{
		int i;
		for(i=0;i<NUM_CUPS;i++){
			if(cup[i]<s.cup[i])return true;
			if(cup[i]>s.cup[i])return false;
		}
		for(i=0;i<NUM_MEN;i++){
			if(man[i]<s.man[i])return true;
			if(man[i]>s.man[i])return false;
		}
		return false;
	}
	bool operator!=(const State& s)const{return !(*this == s);}
	bool operator==(const State& s)const{
		int i;
		for(i=0;i<NUM_CUPS;i++){
			if(cup[i]!=s.cup[i])return false;
		}
		for(i=0;i<NUM_MEN;i++){
			if(man[i]!=s.man[i])return false;
		}
		return true;
	}
	void dump()const{
		cout<<(int)cup[0]<<','<<(int)cup[1]<<','<<(int)cup[2]<<'['<<(int)man[0]<<','<<(int)man[1]<<','<<(int)man[2]<<','<<(int)man[3]<<']'<<'\n';
	}
};

static char maxsize[3]={8,8,3};
typedef map<State,State> StateMap;
typedef list<State> StateStack;
StateMap sMap;
StateStack sStack;


int _tmain(int argc, _TCHAR* argv[])
{
	State s,e;
	int i,j,k;
	s.cup[0]=8;s.cup[1]=8;s.cup[2]=0;s.man[0]=s.man[1]=s.man[2]=s.man[3]=0;
	e.cup[0]=e.cup[1]=e.cup[2]=0;e.man[0]=e.man[1]=e.man[2]=e.man[3]=4;
	sMap.insert(make_pair(e,e));
	sStack.push_back(e);
	while(!sStack.empty()){
		State cur = sStack.front();
		sStack.pop_front();
		for(i=0;i<NUM_CUPS;i++)for(j=0;j<NUM_CUPS;j++){
			if(j==i)continue;
			//try to that some wine is moving from cup i to cup j
			if(cur.cup[j]==0)continue;
			//The first case, all wines from i is moved to j
			if(cur.cup[i] == 0){
				for(k=1;k<=cur.cup[j];k++){
					State tmp = cur;
					tmp.cup[j]-=k;
					tmp.cup[i]=k;
					if(sMap.find(tmp)!=sMap.end())continue;
					sStack.push_back(tmp);
					sMap.insert(make_pair(tmp, cur));
					if(tmp == s)goto found;
				}
			}
			//The second case, j is filled
			if(cur.cup[j]==maxsize[j]){
				for(k=1;k<=cur.cup[j];k++){
					if(cur.cup[i]+k>maxsize[i])break;
					State tmp=cur;
					tmp.cup[j]-=k;
					tmp.cup[i]+=k;
					if(sMap.find(tmp)!=sMap.end())continue;
					sStack.push_back(tmp);
					sMap.insert(make_pair(tmp,cur));
					if(tmp == s) goto found;
				}
			}
		}
		for(k=0;k<NUM_CUPS;k++){
			if(cur.cup[k]!=0)continue;//try to find a case that one man drink all wine in the cup
			for(i=0;i<NUM_MEN;i++){
				if(cur.man[i]>0){
					int max_drink = cur.man[i];
					if(k==NUM_CUPS-1&&max_drink>3)max_drink=3;//The last cup has at most 3
					for(j=1;j<=max_drink;j++){
						State tmp = cur;
						tmp.man[i]-=j;
						tmp.cup[k]=j;
						if(sMap.find(tmp)!=sMap.end())continue;
						sStack.push_back(tmp);
						sMap.insert(make_pair(tmp, cur));
						if(tmp==s)goto found;
					}
				}
			}
		}
	}
found:
	if(sMap.find(s)==sMap.end()){
		cout<<"Fail to find a result\n";
		return -1;
	}
	State cur = s;
	cur.dump();
	while(cur!=e){
		StateMap::iterator it = sMap.find(cur);
		cur=it->second;
		cur.dump();
	}
	return 0;
}

mathe 2012-11-21
  • 打赏
  • 举报
回复
就是一个图论问题,也就是找一条连通路径即可,广度或深度优先均可
失落夏天 2012-11-20
  • 打赏
  • 举报
回复
引用 3 楼 lxzcyh 的回复:
假设四个人是甲、乙、丙和丁,以下数字格式: 8斤瓶 8斤瓶 3斤瓶 [甲 乙 丙 丁] 8 8 0[0 0 0 0] 8 5 3[0 0 0 0] 8 5 0[3 0 0 0] 8 2 3[3 0 0 0] 8 0 3[3 2 0 0] 8 3 0[3 2 0 0] 5 3 3[3 2 0 0] 5 6 0[3 2 0 0] 2 6 3[3 2 0 0] 2 8 1[3 2 ……
恩,方法就是这个方法,问题是怎么用计算机语言算出来,这是难点。
chenzhichao2008 2012-11-20
  • 打赏
  • 举报
回复
主要应该是如何从一起始状态搜索到另一个状态吧。
WizardOz 2012-11-20
  • 打赏
  • 举报
回复
用程序解不会解,直接解倒是知道答案。
总觉得把这种题出为程序题是何等蛋疼。
sxcong 2012-11-19
  • 打赏
  • 举报
回复
题目不完整吧,4个人分,怎么也要4个杯子才行。只有3个杯子,要两人用一个杯子,再醉的人也受不了。
RobertC 2012-11-19
  • 打赏
  • 举报
回复
假设四个人是甲、乙、丙和丁,以下数字格式: 8斤瓶 8斤瓶 3斤瓶 [甲 乙 丙 丁] 8 8 0[0 0 0 0] 8 5 3[0 0 0 0] 8 5 0[3 0 0 0] 8 2 3[3 0 0 0] 8 0 3[3 2 0 0] 8 3 0[3 2 0 0] 5 3 3[3 2 0 0] 5 6 0[3 2 0 0] 2 6 3[3 2 0 0] 2 8 1[3 2 0 0] 2 8 0[3 2 1 0] 2 5 3[3 2 1 0] 7 0 3[3 2 1 0] 7 3 0[3 2 1 0] 4 3 3[3 2 1 0] 4 6 0[3 2 1 0] 1 6 3[3 2 1 0] 0 6 3[3 2 1 1] 0 8 1[3 2 1 1] 0 8 0[4 2 1 1] 0 5 3[4 2 1 1] 0 5 0[4 2 4 1] 0 2 3[4 2 4 1] 0 2 0[4 2 4 4] 0 0 0[4 4 4 4]
失落夏天 2012-11-19
  • 打赏
  • 举报
回复
引用 1 楼 sxcong 的回复:
题目不完整吧,4个人分,怎么也要4个杯子才行。只有3个杯子,要两人用一个杯子,再醉的人也受不了。
这道题是绝对可以解出来的。要么就没必要出题了。 另外不用考虑醉不醉的问题啊。

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧