`
bolide74
  • 浏览: 84172 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

多线程算法题:国王、毒酒、侍卫

阅读更多
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少"人月"来完成这个工作。

为了避免再有人走歪门邪道。。。   我改了一下   毒药发作时间不确定正好半小时,只能说半小时左右,按体质不同发作时间不定,即不一定先喝的就先死

以上限制也是为了体现多线程并发的一般情况,毕竟无阻塞并发本来就很难判断哪个线程先跑完
分享到:
评论
48 楼 xbcoil 2011-04-22  
我服了...犀利啊
47 楼 heisedeyueya 2011-04-22  
zhanghh321 写道
albertshaw 写道
ppgunjack 写道
其实过不一秒也无所谓,但是实际是分两轮
1个10x10矩阵,里面有个点是1(有毒),其余是0,第一轮10个人同时喝纵向的酒,第二轮过后这10个人喝所有横向,一般会先后死2个,如果毒酒在5×5这种平方位置则就一个人死
扩展开又可以分成5×5×5把100划分到125的3维矩阵,每轮5线程覆盖该平面的25个桶,最后死的顺序3个人能确定i,j,k


我觉得这个解挺好的呀,为什么没人评论一下呢?


这个算法是有问题的,比如处于1号位和2号位的侍卫死了的话 你知道是(1,0)还是(0,1)的酒有毒吗?

应该能看出,可以看那个人先死!!!
46 楼 johnnyking 2011-04-22  
mahonet 写道
lyy3323 写道
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。




这个算法有点意思啊。学术名叫什么?
1号侍卫实在悲催。。

还是没看懂……哪位能讲下。。。


两个二进制数相&&
45 楼 dsjt 2011-04-22  
albertshaw 写道
ppgunjack 写道
其实过不一秒也无所谓,但是实际是分两轮
1个10x10矩阵,里面有个点是1(有毒),其余是0,第一轮10个人同时喝纵向的酒,第二轮过后这10个人喝所有横向,一般会先后死2个,如果毒酒在5×5这种平方位置则就一个人死
扩展开又可以分成5×5×5把100划分到125的3维矩阵,每轮5线程覆盖该平面的25个桶,最后死的顺序3个人能确定i,j,k


我觉得这个解挺好的呀,为什么没人评论一下呢?



这个方案挺不错,但三维矩阵有bug,
死一个或者死三个可以确定坐标;
死两个怎么办?
比如 2号死然后是3号死; 存在两种情况:2,2,3 或者2,3,3
除非还要计算其死亡的时间间隔和喝酒的时间间隔;否则就要再有一个人喝一次;





不知道 2^7与5×5×5 这两种方案哪一个在理论上死的人最少


44 楼 zhanghh321 2011-04-22  
albertshaw 写道
ppgunjack 写道
其实过不一秒也无所谓,但是实际是分两轮
1个10x10矩阵,里面有个点是1(有毒),其余是0,第一轮10个人同时喝纵向的酒,第二轮过后这10个人喝所有横向,一般会先后死2个,如果毒酒在5×5这种平方位置则就一个人死
扩展开又可以分成5×5×5把100划分到125的3维矩阵,每轮5线程覆盖该平面的25个桶,最后死的顺序3个人能确定i,j,k


我觉得这个解挺好的呀,为什么没人评论一下呢?


这个算法是有问题的,比如处于1号位和2号位的侍卫死了的话 你知道是(1,0)还是(0,1)的酒有毒吗?
43 楼 zhanghh321 2011-04-22  
albertshaw 写道
ppgunjack 写道
其实过不一秒也无所谓,但是实际是分两轮
1个10x10矩阵,里面有个点是1(有毒),其余是0,第一轮10个人同时喝纵向的酒,第二轮过后这10个人喝所有横向,一般会先后死2个,如果毒酒在5×5这种平方位置则就一个人死
扩展开又可以分成5×5×5把100划分到125的3维矩阵,每轮5线程覆盖该平面的25个桶,最后死的顺序3个人能确定i,j,k


我觉得这个解挺好的呀,为什么没人评论一下呢?

我觉得这种算法是有点问题的,假设10个人横向喝一次,然后纵向喝一次的话,如果是1号位喝0号位的侍卫死了的话你是看不出到底是哪瓶有毒的。
42 楼 Bruce.Sun 2011-04-22  
511930751 写道
时间最少的方法是:100个侍卫喝。30分钟有效果。

这个认同

511930751 写道
小兵死亡最少的方法是:1个喝,30分+100秒有效果。。

这个不认同,因为前提是你假设士兵1秒喝一桶
41 楼 kingkan 2011-04-22  
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。

public class Client {

	public static void main(String[] args) {
		HashMap<Integer,Boolean> jiuMap = getJiuMap(100);
		HashMap<Integer,Boolean> shiMap = getShiMap(7);
		for (Map.Entry<Integer,Boolean> entryShi : shiMap.entrySet()) {
			for (Map.Entry<Integer,Boolean> entryJiu : jiuMap.entrySet()) {
				if((entryShi.getKey() & entryJiu.getKey()) == entryShi.getKey()){
					if(!entryJiu.getValue().booleanValue()){
						entryShi.setValue(false);
					}
				}
			}
		}
		//try { Thread.sleep(30*60*1000); } catch (InterruptedException e) {}
		int dujiu = 0;
		for (Map.Entry<Integer,Boolean> entryShi : shiMap.entrySet()) {
			if(!entryShi.getValue()){
				dujiu = dujiu | entryShi.getKey();
			}
		}
		System.out.println("毒酒二进制:"+Integer.toBinaryString(dujiu));
	}
	
	private static HashMap<Integer,Boolean> getShiMap(int shiNumber) {
		System.out.println("侍卫数:"+shiNumber);
		HashMap<Integer,Boolean> shiMap = new HashMap<Integer,Boolean>();
		for (int i = 0; i < shiNumber; i++) {
			int shi = 1 << i;
			shiMap.put(shi, true);
		}
		return shiMap;
	}
	private static HashMap<Integer,Boolean> getJiuMap(int jiuNumber) {
		HashMap<Integer,Boolean> jiuMap = new HashMap<Integer,Boolean>();
		int dujiu = (int) (1 + Math.random() * jiuNumber);
		System.out.println("酒数量:"+jiuNumber);
		System.out.println("毒酒号:"+dujiu);
		for (int i = 1; i <= jiuNumber; i++) {
			if(i == dujiu){
				jiuMap.put(i, false);
			}else{
				jiuMap.put(i, true);
			}
		}
		return jiuMap;
	}

}


随便整整,各位童鞋别拍砖啊,呵呵。
40 楼 mcqueen 2011-04-22  
有点意思  
39 楼 albertshaw 2011-04-22  
ppgunjack 写道
其实过不一秒也无所谓,但是实际是分两轮
1个10x10矩阵,里面有个点是1(有毒),其余是0,第一轮10个人同时喝纵向的酒,第二轮过后这10个人喝所有横向,一般会先后死2个,如果毒酒在5×5这种平方位置则就一个人死
扩展开又可以分成5×5×5把100划分到125的3维矩阵,每轮5线程覆盖该平面的25个桶,最后死的顺序3个人能确定i,j,k


我觉得这个解挺好的呀,为什么没人评论一下呢?
38 楼 jtyb 2011-04-22  
学习一下思想
37 楼 kingkan 2011-04-22  
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。


这种方式比较符合计算机编程。
36 楼 liuyupy 2011-04-22  
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。



前段日子出过小白鼠实验题。。。也是一样解法。
35 楼 semmy 2011-04-21  
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。

起初没看明白,现在总算看明白了
34 楼 orcl_zhang 2011-04-21  
kimmking 写道
bolide74 写道
国王有一百桶酒,比自己的生命还重要。结果有一天其中一桶被投了慢性毒药,喝了以后半个小时以后就会死掉。
国王大怒,命令玩忽职守的侍卫去试毒。
酒不能被混合,怎么样才能用最少的侍卫、在最短的时间知道哪桶是毒酒。

侍卫可以理解为线程,即怎么样用最少的线程用最快的速度完成这个工作。

100 < 128 = 2^7

找7个侍卫,编号1-7                             1234567

100桶酒,编号1-100
每个编号表示成2进制,不超过7位,前面补上0成7位,比如0000001
从第一位到第七位,如果是1,让序号为此位的侍卫喝此酒。

半小时后,哪几个侍卫死了,就在他所在的位置置1,活的置0
得到一个7位的二进制 0010101,转成十进制,就是有毒的酒桶序号。

33 楼 evanzzy 2011-04-21  
学习一下算法
32 楼 kxys422834 2011-04-21  
新手学习了!
31 楼 rongsantang 2011-04-21  
提供一个跟程序员相关的思路:二分查找法
30 楼 fellatioyzx 2011-04-21  
又见月经贴,1000桶酒10个小白鼠试毒的面试题网上早就传遍了好吧。
29 楼 许文强 2011-04-21  
bolide74 写道
那就直接一点吧   在正好半小时时间的的前提下,怎么样用最少的侍卫找出毒酒,最好还能让每个侍卫试的次数尽量均衡,也就是让各线程的负载尽量均衡
假设侍卫能瞬间同时试喝N桶的酒。。。。


考的是算法,我想连这个题目想表达哪种多线程状况都还没搞明白的同学,就别再去钻题目文字层面上的牛角尖了吧....

你这么一说我就懂了,线程可以由自己定,没有最优解,最多是个统计的问题。

相关推荐

    Qt多线程可视化多线程排序算法演示:冒泡和快排

    资源描述:基于Qt的可视化界面,编写的冒泡排序和可视化排序的比较算法,通过生成10000个随机数,多线程进行排序比较,可直观看到时间复杂度对程序运行的影响程度。 可以学到的知识:Qt多线程,多进程,冒泡排序算法...

    多线程面试题

    本文将围绕“多线程面试题”这一主题,深入探讨相关概念、技术及其应用。 1. **线程的概念**:线程是程序执行的最小单位,一个进程可以有多个线程同时执行任务,提高了程序的运行效率。 2. **Java中的线程创建方式...

    CC++多线程编程练习题大全

    **CC++多线程编程**是现代软件开发中的重要组成部分,尤其在高性能计算、服务器端应用和实时系统中,多线程技术能充分利用多核处理器的资源,提高程序的执行效率。以下是一些关于CC++多线程编程的核心知识点: 1. *...

    JAVA多线程练习题答案。

    JAVA多线程练习题答案详解 在本文中,我们将对 JAVA 多线程练习题的答案进行详细的解释和分析。这些题目涵盖了 JAVA 多线程编程的基本概念和技术,包括线程的生命周期、线程同步、线程状态、线程优先级、线程安全等...

    Java多线程练习题

    "多线程试卷.doc"和"多线程试卷参考答案.doc"提供了丰富的练习题,可以帮助你巩固和提高这方面的技能。通过这些题目,你可以检验自己对Java多线程的理解程度,并通过解答参考答案来查漏补缺,进一步提升自己的编程...

    可并行递归算法的递归多线程实现

    ### 可并行递归算法的递归多线程实现:深入解析 #### 引言:多线程与并行处理的重要性 随着计算任务日益复杂,传统的单线程编程模型已无法满足高效处理大规模数据的需求。多线程编程作为一种提高程序并发性和性能...

    多线程RC4算法加解密

    3. **线程安全**:在多线程环境中,需要注意RC4算法的线程安全问题,例如防止状态数组在同一时刻被多个线程修改,通常可以通过锁机制来解决。 **三、日志输出** 1. **目的**:日志输出有助于追踪程序运行状态,...

    人工智能-项目实践-多线程-Paxos算法的多线程实现.zip

    总的来说,Paxos算法的多线程实现是将分布式一致性理论与实际编程技术结合的体现,它需要深入理解Paxos算法的工作原理以及Java多线程机制,以构建出高效且稳定的分布式系统。在这个过程中,还需要考虑性能优化、容错...

    QT多线程处理不同算法计算

    在本项目中,我们关注的是如何利用QT框架来实现多线程处理不同的算法计算,特别是排序算法。QT是一个跨平台的应用开发框架,广泛应用于桌面、移动以及嵌入式系统。它提供了一套丰富的API,使得开发者可以方便地创建...

    多线程代码 经典线程同步互斥问题 生产者消费者问题

    b: 创建多个线程 c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 g: 利用互斥量来解决线程同步互斥问题 h: problem1 生产者消费者问题 (1...

    java用多线程进行排序算法的比较

    在这个特定的项目中,“java用多线程进行排序算法的比较”关注的是如何利用多线程技术来实现和比较不同的排序算法,尤其是快速排序。下面我们将详细探讨多线程在排序算法中的应用以及快速排序的原理。 首先,我们要...

    linux多线程编程.pdf

    Linux 多线程编程是指在 Linux 操作系统中使用多线程技术来提高程序的执行效率和响应速度。多线程编程可以让程序同时执行多个任务,从而提高程序的整体性能。 线程基础知识 什么是线程?线程(Thread)是操作系统...

    java多线程面试题59题集合

    以下是对Java多线程面试题59题集合中可能涉及的一些关键知识点的详细解析。 1. **线程的创建方式** - 继承Thread类:创建一个新的类,该类继承自Thread类,并重写其run()方法。 - 实现Runnable接口:创建一个实现...

    矩阵乘法的多线程算法

    矩阵乘法的多线程算法利用了现代计算机中的多核处理器特性,通过并行计算来提高矩阵乘法的运算速度。 在多线程矩阵乘法算法中,每个工作线程负责计算输出矩阵C的一个元素。具体而言,矩阵C的每个元素C[i][j]都是...

    银行家算法简单实现(多线程 VC)

    用多线程模拟多进程实现银行家算法,或者不是最好,但是有效,程序写的较乱

    MD5 加密算法源码(支持多线程)

    在"MD5 加密算法源码(支持多线程)"中,我们关注的是MD5算法的实现以及其多线程支持。多线程是现代计算机程序设计中的一个重要概念,尤其是在处理大量数据或者需要提升执行效率时。MD5算法本身是顺序计算的,但通过多...

    热门Java面试多线程面试题问答Top50共17页.pdf

    【标题】"热门Java面试多线程面试题问答Top50共17页.pdf" 提供了一份关于Java多线程面试的重要资源,涵盖了面试中可能会遇到的50个关键问题和答案,共计17页。这表明该文档深入探讨了Java编程中的并发处理和线程管理...

    Java面试题、JVM面试题、多线程面试题、并发编程、设计模式面试题

    Java面试题、JVM面试题、多线程面试题、并发编程、设计模式面试题、SpringBoot面试题、SpringCloud面试题、MyBatis面试题、Mysql面试题、VUE面试题、算法面试题、运维面试题。 收集汇总各行业笔试or编程题解题思路 ...

    单元列表算法的 Julia 语言实现,用于解决固定半径近邻问题,包括串行和多线程算法_julia_代码_下载

    我们还将算法扩展到多线程版本,我们在 Julia 语言中的 Julia 语言中的多线程应用于单元列表算法一文中对此进行了解释。 引文 您可以CellLists.jl通过导航到 Zenodo 提供的DOI来引用存储库和代码,然后从“导出”...

Global site tag (gtag.js) - Google Analytics