题目:
村子中有50个人,每人有一条狗。在这50条狗中有病狗(这种病不会传染)。于是人们就要找出病狗。
每个人可以观察其他的49条狗,以判断它们是否生病(如果有病一定能看出来),只是自己的狗不能看。
观察后得到的结果不得交流,也不能通知病狗的主人,一天只能看一次。主人一旦推算出自己家的是病狗就要枪毙自己的狗(发现后必须在一天内枪毙),
而且每个人只有权利枪毙自己的狗,没有权利打死其他人的狗。
第一天大家全看完了,但枪没有响,第二天仍没有枪响。到了第三天传来一阵枪声,
问村里共有几条病狗,如何推算得出?
=======================================
1. 思考: 第一时间还没有想到直接求解的办法。先采用假设法,简化处理。呵呵。。
假设有1只狗,第几天会有枪声。
假设有2只狗,第几天会有枪声。
。。。
2. 解法: 按照这个思路。将信息抽象为两个类。村庄和拥有狗的村民。
村民
拥有一支狗,且狗的状态不可变。
有查看别人家狗的动作。
有kill自己狗的动作。
另外,还需要提供一个,供别人查看自己的狗状态的动作。
村庄(简化为村庄的村长来组织/发起动作。。村庄与村长奇妙的合体了。。。。哈哈、、)
村庄有村民入住动作。
村长组织村民 看狗。。。
村长给村民一段时间,用来杀自己家狗。
3. 总结:
如果按照这个解法来看,能够用到的技术主要是并发计算了。
1). 在每个人和每个人的动作互相独立,没有关联,可以完全解耦。可以并行。
2). 每个人在观察完所有狗(除了自己)之后就有了判断,可以决定杀还是不杀了。
3). 每天的事件也可以做到并行处理。但是会出现过度计算的问题。需要增加中断和撤销机制。
第一时间没有想到更好的解决方案。哎。思维短板啊。。。。。
附code:
import java.util.List; /** * Created by zkai on 2015/1/21. */ public class PetOwner { private final boolean isSickDog; private boolean consideredOwnerSickDog; public PetOwner(boolean isSickDog) { this.isSickDog = isSickDog; } /** * @param day 第几天 * @return 看到病狗的数量 */ public boolean watchOtherDogAndThink(int day, List<PetOwner> petOwners) { int count = 0; for (PetOwner petOwner : petOwners) { if (petOwner != this && petOwner.dogStatus(this)) { count++; } } // 此处是最关键的。day 与 count 的关系。 consideredOwnerSickDog = day - count == 1; // 看到病狗的数量,和日期的关系。 return consideredOwnerSickDog; } /** * * @return 是否枪杀了自己的狗。true:杀了,false:没杀 */ public boolean killMyselfDog() { if (consideredOwnerSickDog) { System.out.println("▄︻┳═一 枪杀自己的狗~~~ 嘭~~~"); } return consideredOwnerSickDog; } /** * 查看狗的状态,必须是非自己 * @param watcher * @return */ public boolean dogStatus(PetOwner watcher) { if (watcher == null || watcher == this) { throw new IllegalStateException("自己不能看自己的狗"); } return isSickDog; } }
package com.wyfbilling.common.logger.contract; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * * * * Created by zkai on 2015/1/21. */ public class Village { private final List<PetOwner> petOwners; /** * * @param petOwnerCount 村民数量 * @param sickDogCount 病狗的数量 */ public Village(int petOwnerCount,int sickDogCount) { petOwners = Collections.unmodifiableList(init(petOwnerCount, sickDogCount)); } /** * 村民入住 * @param petOwnerCount 村民数量 * @param sickDogCount 病狗的数量 */ private List<PetOwner> init(int petOwnerCount, int sickDogCount) { List<PetOwner> list = new ArrayList<>(); for (int i = 0; i < petOwnerCount; i++) { PetOwner petOwner; if (i < sickDogCount) { // 拥有病狗的主人 petOwner = new PetOwner(true); } else { // 拥有健康狗的主人 petOwner = new PetOwner(false); } list.add(petOwner); } return list; } /** * 观察狗,并思考自己拥有的是否是病狗 * @param day */ public void watchDogAndThinkTime(int day) { for (PetOwner petOwner : petOwners) { petOwner.watchOtherDogAndThink(day, petOwners); } } /** * 杀狗时间。。。 * * @return 是否有杀狗动作 true:有村民杀了狗。 */ public int killDogTime() { int killDogEventCount = 0; for (PetOwner petOwner : petOwners) { if (petOwner.killMyselfDog()) killDogEventCount++; } return killDogEventCount; } public static void main(String[] args) { Village village = new Village(50, 10);// 假设一个村庄有50个村民,有3只病狗。 for (int day = 1; day < 10000; day++) {// 防御式编程,day设置最大,防止编程错误导致无限循环。 village.watchDogAndThinkTime(day); int killDogEventCount = village.killDogTime(); if (killDogEventCount > 0) { System.out.format("今天是第%d天,今天发生了%s次枪击事件!!!", day, killDogEventCount); break; } } } }
相关推荐
在这50条狗中有病狗(这种病不会传染)。于是人们就要找出病狗。每个人可以观察其他的49条狗,以判断它们是否生病,只有自己的狗不能看。观察后得到的结果不得交流,也不能通知病狗的主人。主人一旦推算出自己家的是...
java工程师职位招聘时,一些有趣的面试智力题,
Logic-Interview-Questions 逻辑推理面试题目 题目列表: 1、翻硬币:将硬币分成两堆并确保两堆硬币正面朝上的硬币数量一致。...3、病狗:村里有病狗,通过观察和枪声发现病狗; 4、买鸡:买入、卖出算盈利;
目录IBM面试:几只狗生病腾讯面试题:给出上排数,写出下排数阿里巴巴面试题:男女比例淘宝笔试题:N个鸡蛋放到M个篮子中百度移动开发笔试题:荷兰国旗(三色球排序问题) IBM面试:几只狗生病 村子中有50个人,每人...
面试题2:村里有多少条病狗 面试题3:他们都在做什么 面试题4:躯体与灵魂 面试题5:小明一家能否安全过桥 面试题6:过河 问题 面试题7:这是张什么牌 面试题8:说谎岛上的两个部落 面试题9:谁是特尔斐城的预言家 ...