`
fly0wings
  • 浏览: 35231 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

病狗问题 -- 假设法求解

阅读更多

 

题目:

    村子中有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;
            }
        }
    }
}

 

 

0
6
分享到:
评论
2 楼 fly0wings 2015-01-21  
oham_一1一 写道
“一天只能看一次”,这个条件在问题描述中不能少


恩,是的。
1 楼 oham_一1一 2015-01-21  
“一天只能看一次”,这个条件在问题描述中不能少

相关推荐

    中外名企面试笔试智力题大搜罗

    - "鸟飞行距离"问题则涉及速度、时间与距离的三角关系,通过求解相遇时间来确定鸟的飞行距离。 这些题目不仅测试了应聘者的智力,还评估了他们的逻辑思维、数学应用、问题解决、时间管理和空间感知等多方面的能力...

    知名公司招聘面试题.pdf

    1. **逻辑推理与问题解决** - 题目1:这是一个经典的逻辑推理题。问题的关键在于理解每个人只能通过观察别人的狗来判断。如果有1条病狗,所有人第一天都会看到,但没有人开枪,因为他们不确定自己的狗是否病了。...

    \IBM面试的IQ测试题

    这道题考查了考生的逻辑思维能力,需要使用排除法和假设法来解决问题。 第二道题:有两根不均匀分布的香,每根香烧完的时间是一个小时,你能用什么方法来确定一段 45 分钟的时间?这道题考查了考生的数学思维能力,...

    求职-IBM的经典面试题

    这个问题是IBM面试中一个著名的逻辑推理题,通常用于考察应聘者的逻辑思维能力和问题解决能力。题目设置在一个人人皆知的背景下,即一个村子里有50个人,每人都有一条狗,其中有些狗生病了,但病狗不会传染。村民们...

    IBM经典面试题IBM公司向来以高素质人才作为企业持续竞争力的保证。进入IBM公司是差不多每个IT人的梦想,偶然看到这条IBM公司的面试题,给大家试试看,看看是否具备进入IBM的实力!

    这个问题是经典的逻辑推理题,常出现在IBM等知名企业的面试中,用以测试候选人的逻辑思维和问题解决能力。题目描述了一个假设的村庄情景,其中50个人各自拥有一条狗,其中有一些狗生病了,但是不能互相沟通。目标是...

    益智题 趣味益智题目 使人聪明的体操 一般企业面试也用哦

    9. **病狗问题**: - 推理过程:村民们在第一天没有开枪,说明没有人生病或所有人都知道病狗不止一条。在第二天也没有开枪,那么所有人都能确定有两条病狗。在第三天,病狗的主人会意识到自己的狗也是病狗,因为...

    IBM历年面试题目.pdf

    1. **逻辑推理能力**:IBM面试中的"病狗问题"是一个典型的逻辑推理题,旨在考察应聘者的思维敏捷度和推理能力。在这个问题中,关键在于理解每个村民只能看到其他49条狗,无法看到自己的狗,且不能交流。如果只有一条...

    招募面试IBM集团经典面试题.doc

    在这个问题中,村子有50个人,每人养了一条狗,其中一些狗是病狗,但主人不知道自己的狗是否生病。每个人可以看到其他49条狗,但不能看到自己的狗,也不能交流观察结果。如果主人确定自己的狗是病狗,就必须将其枪毙...

    最新微软谷歌Google面试题怪题

    这些题目并非寻找标准答案,而是评估应聘者的思维方式和解决问题的策略。 1. **美国有多少辆汽车** - 微软 这是一个典型的谜语类问题,目的是测试应聘者的应变能力和逻辑推理。微软期望看到的不是具体的数字,而是...

    中外名企面试笔试智力题大搜罗.doc

    11. **病狗问题**: 村民无法确定自己家的狗是否病狗,但可以通过观察别人家的狗来推断。如果第一天无人开枪,说明至少有1条病狗;第二天依旧无人开枪,说明至少有2条病狗。第三天开枪,说明只有一条病狗,因为如果...

    软件测试面试和笔试题汇总

    如井盖是圆形因为可以任意方向滚动,车辆数量、下水道井盖数量难以准确估计,金条问题需要分割成1/3和2/3,火车与鸟的问题关注相对速度,颜色传感器问题需要至少一个传感器在分界线上,时针与分针重叠的问题涉及时间...

    IT 130套经典面试题

    在这50条狗中有病狗(这种病不会传染)。于是人们就要找出病狗。每个人可以观察其他的49条狗,以判断它们是否生病,只有自己的狗不能看。观察后得到的结果不得交流,也不能通知病狗的主人。主人一旦推算出自己家的是...

    智力题-考考你的推断能力

    2. 病狗问题:第一天没枪声表示没有狗生病,第二天也没枪声意味着所有狗都在等待,第三天枪声响起,说明有一只狗被射杀。如果有两只狗生病,第一天会有一只被射杀,因为其余48户都能看到有病狗。但第一天没有枪声,...

    面试逻辑题目汇总.doc

    5. **病狗问题**:在第一天没有人枪毙狗,说明至少有一户看到了不止一条病狗。如果只有一条病狗,主人会看到其他49条狗健康,就会推断出自己的狗是病狗。所以,第一天没枪响说明至少有两条病狗。同理,第二天也没有...

    java的一些面试题

    - **病狗问题**:这是一个经典的逻辑推理问题。假设每户都知道其他家的狗是否生病,但不知道自己家的狗。经过7天,所有病狗被处决,说明每个狗主人在第7天都能确定自己家的狗是病狗,因为他们看到其他健康的狗在前6...

    经典面试资料

    2. IBM_病狗问题.txt:IBM的面试题可能涉及到复杂的问题解决,例如“病狗问题”可能是一个涉及逻辑推理和策略的问题。这种题目要求应聘者在有限的信息条件下做出判断,展示他们分析问题的能力。 3. 安全清除你C盘...

Global site tag (gtag.js) - Google Analytics