解决爱因斯坦出的头脑风暴测试题

        经常遇见这样的问题,却往往没人回答,于是发贴者洋洋自得?猜的,哈哈。
或许在那个年代,要做出这样的问题非常难,我感到奇怪的是爱因斯坦为什么出这样的题目,考察人的什么思维?又是怎么出的?难道考察天才的某一特性:解决问题时拥有超强的暂时记忆,能容忍很大的不确定性?
现在还拿出来吼吼,当我们程序员不存在,郁闷之余,逐写代码解决。

 解题思路:
1.1~15个已知条件写成c1~15个条件方法;
2.预先求1..5的所有排列;
3.对每个属性进行排列;
4.对6个属性的排列进行组合;
5.上面的排列组合有24.8832亿种,每种组合在合适的位置过滤1~15个条件(合适位置的选择:条件关联的属性已被赋值,且最浅循环。);
6.执行结果有7种排列组合,其中可能养鱼的分别有:德国、挪威、丹麦

package  com.game;

import  java.util.ArrayList;
import  java.util.Arrays;
import  java.util.List;

/**
 * 
<pre>
    爱因斯坦出的测试题,据说世界98%的人答不出!来看看这道爱因斯坦出的测试题, 他说世界上有98%的人回答不出, 
    看看你是否属于另外的2%:
    1. 有5栋5种颜色的房子 
    2. 每一位房子的主人国籍都不同 
    3. 这5个人每人只喝一个牌子的饮料, 只抽一个牌子的香烟, 只养一 
    种宠物 
    4. 没有人有相同的宠物, 抽相同牌子的香烟, 喝相同的饮料 
    已知条件: 
    1. 英国人住在红房子里 
    2. 瑞典人养了一条狗 
    3. 丹麦人喝茶 
    4. 绿房子在白房子左边 
    5. 绿房子主人喝咖啡 
    6. 抽PALL MALL烟的人养了一只鸟 
    7. 黄房子主人抽DUNHILL烟 
    8. 住在中间那间房子的人喝牛奶 
    9. 挪威人住在第一间房子 
    10. 抽混合烟的人住在养猫人的旁边 
    11. 养马人住在DUNHILL烟的人旁边 
    12. 抽BLUE MASTER烟的人喝啤酒 
    13. 德国人抽PRINCE烟 
    14. 挪威人住在蓝房子旁边 
    15. 抽混合烟的人的邻居喝矿泉水
    问题是:谁养鱼?
</pre>
 * 
@author zfzheng
 * {
@value 不好意思,偶便是2%中较笨的一个 :)}
 *
 
*/

public   class  EinsteinProblem  {
    
private final static int[] NO={1,2,3,4,5};
    
private final static String[] COLOR={"","","绿","",""};
    
private final static String[] NATIONALITY={"英国","瑞典","丹麦","挪威","德国"};
    
private final static String[] DRINK={"","咖啡","牛奶","啤酒","矿泉水"};
    
private final static String[] SMOKE={"PALL MALL","DUNHILL","BLUE MASTER","PRINCE","混合烟"};
    
private final static String[] PET={"","","","",""};
    
//排列列表,{[1,2,3,4,5],[1,2,3,5,4],......}
    private List<int[]> pList=new ArrayList<int[]>();
    
    
static class Combine{
        
int no;//房间编号
        String color;//房子颜色
        String nationality;//国籍
        String drink;//饮料
        String smoke;//香烟
        String pet;//宠物        
        
        
public String toString(){
            
return no+" "+color+" "+nationality+" "+drink+" "+smoke+" "+pet;
        }

    }

    
    
// 1. 英国人住在红房子里 
    private boolean c1(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.nationality.equals("英国")){
                
return item.color.equals("");
            }

        }

        
return false;
    }

    
    
//2. 瑞典人养了一条狗 
    private boolean c2(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.nationality.equals("瑞典")){
                
return item.pet.equals("");
            }

        }

        
return false;
    }
    
    
    
//3. 丹麦人喝茶 
    private boolean c3(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.nationality.equals("丹麦")){
                
return item.drink.equals("");
            }

        }

        
return false;
    }
    
    
    
//4. 绿房子在白房子左边 
    private boolean c4(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.color.equals("绿")){
                
for(int j=i+1;j<n;j++){
                    
if(items[j].color.equals("")){
                        
return true;
                    }

                }

                
return false;
            }

        }

        
return false;
    }
    
    
    
// 5. 绿房子主人喝咖啡  
    private boolean c5(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.color.equals("绿")){
                
return item.drink.equals("咖啡");
            }

        }

        
return false;
    }
    

    
//6. 抽PALL MALL烟的人养了一只鸟 
    private boolean c6(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("PALL MALL")){
                
return item.pet.equals("");
            }

        }

        
return false;
    }
    
    
    
//7. 黄房子主人抽DUNHILL烟 
    private boolean c7(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("DUNHILL")){
                
return item.color.equals("");
            }

        }

        
return false;
    }

    
    
//8. 住在中间那间房子的人喝牛奶 
    private boolean c8(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.no==3){
                
return item.drink.equals("牛奶");
            }

        }

        
return false;
    }

    
    
//9. 挪威人住在第一间房子
    private boolean c9(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.no==1){
                
return item.nationality.equals("挪威");
            }

        }

        
return false;
    }

    
//10. 抽混合烟的人住在养猫人的旁边 
    private boolean c10(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("混合烟")){
                
return (i>0&&items[i-1].pet.equals(""))||(i<n-1&&items[i+1].pet.equals(""));
            }

        }

        
return false;
    }
    
    
    
//11. 养马人住在DUNHILL烟的人旁边 
    private boolean c11(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("DUNHILL")){
                
return (i>0&&items[i-1].pet.equals(""))||(i<n-1&&items[i+1].pet.equals(""));
            }

        }

        
return false;
    }

    
    
//12. 抽BLUE MASTER烟的人喝啤酒 
    private boolean c12(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("BLUE MASTER")){
                
return item.drink.equals("啤酒");
            }

        }

        
return false;
    }
    
    
    
//13. 德国人抽PRINCE烟 
    private boolean c13(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("PRINCE")){
                
return item.nationality.equals("德国");
            }

        }

        
return false;
    }
    
    
    
// 14. 挪威人住在蓝房子旁边 
    private boolean c14(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.nationality.equals("挪威")){
                
return (i>0&&items[i-1].color.equals(""))||(i<n-1&&items[i+1].color.equals(""));
            }

        }

        
return false;
    }
    
    
    
// 15. 抽混合烟的人的邻居喝矿泉水  
    private boolean c15(Combine[] items){
        Combine item;
        
for(int i=0,n=items.length;i<n;i++){
            item
=items[i];
            
if(item.smoke.equals("混合烟")){
                
return (i>0&&items[i-1].drink.equals("矿泉水"))||(i<n-1&&items[i+1].drink.equals("矿泉水"));
            }

        }

        
return false;
    }
    
    
    
private void assignCombine(Combine[] items){
        
int matchedCount=0;
        
int n=pList.size();
        
for(int i_color=0;i_color<n;i_color++){
            assignColor(items,pList.get(i_color));
            
if(!c4(items))continue;// 4. 绿房子在白房子左边 
            for(int i_nationality=0;i_nationality<n;i_nationality++){
                assignNationality(items,pList.get(i_nationality));
                
if(!c1(items))continue;//1. 英国人住在红房子里 
                if(!c9(items))continue;//9. 挪威人住在第一间房子
                if(!c14(items))continue;//14. 挪威人住在蓝房子旁边
                for(int i_drink=0;i_drink<n;i_drink++){
                    assignDrink(items,pList.get(i_drink));
                    
if(!c3(items))continue;//3. 丹麦人喝茶 
                    if(!c5(items))continue;// 5. 绿房子主人喝咖啡 
                    if(!c8(items))continue;//8. 住在中间那间房子的人喝牛奶 
                    for(int i_smoke=0;i_smoke<n;i_smoke++){
                        assignSmoke(items,pList.get(i_smoke));
                        
if(!c7(items))continue;// 7. 黄房子主人抽DUNHILL烟
                        if(!c12(items))continue;//12. 抽BLUE MASTER烟的人喝啤酒 
                        if(!c13(items))continue;//13. 德国人抽PRINCE烟
                        if(!c15(items))continue;//15. 抽混合烟的人的邻居喝矿泉水
                        for(int i_pet=0;i_pet<n;i_pet++){
                            assignPet(items,pList.get(i_pet));
                            
if(!c2(items))continue;//2. 瑞典人养了一条狗 
                            if(!c6(items))continue;//6. 抽PALL MALL烟的人养了一只鸟
                            if(!c10(items))continue;//10. 抽混合烟的人住在养猫人的旁边 
                            if(!c11(items))continue;// 11. 养马人住在DUNHILL烟的人旁边
                            matchedCount++;
                            dumpCombine(items);
                        }

                    }

                }
                
            }

        }
        
        System.out.println(
"Matched count="+matchedCount);
    }
    
    
    
private void assignColor(Combine[] items,int[] order){
        
for(int i=0,n=items.length;i<n;i++){
            items[i].color
=COLOR[order[i]-1];
        }

    }

    
private void assignNationality(Combine[] items,int[] order){
        
for(int i=0,n=items.length;i<n;i++){
            items[i].nationality
=NATIONALITY[order[i]-1];
        }

    }

    
    
    
private void assignDrink(Combine[] items,int[] order){
        
for(int i=0,n=items.length;i<n;i++){
            items[i].drink
=DRINK[order[i]-1];
        }

    }

    
private void assignSmoke(Combine[] items,int[] order){
        
for(int i=0,n=items.length;i<n;i++){
            items[i].smoke
=SMOKE[order[i]-1];
        }

    }

    
private void assignPet(Combine[] items,int[] order){
        
for(int i=0,n=items.length;i<n;i++){
            items[i].pet
=PET[order[i]-1];
        }

    }
    
    
    
    
private void dumpCombine(Combine[] items){
        StringBuffer s
=new StringBuffer();
        
for(int i=0;i<items.length;i++){
            s.append(items[i]).append(
" ");
        }

        System.out.println(s
+" ");
    }

    
    
//排列
    private void readyPermutation(int n){
        pList.clear();
        
boolean[] selected=new boolean[n];
        Arrays.fill(selected, 
false);
        
int[] v=new int[n];
        Arrays.fill(v, 
-1);
        doPermutation(selected,v,n,
0);
    }

    
    
/**
     * 递归、回溯求排列
     
*/

    
private void doPermutation(boolean[] selected, int[] v, int n, int filledCount){
        
for(int i=filledCount;i<n;i++){
            
for(int j=0;j<n;j++){
                
if(!selected[j]){
                    selected[j]
=true;
                    v[i]
=j+1;
                    
if(i==n-1){
                        gatherPermutationResult(v);
                    }

                    doPermutation(selected,v,n,i
+1);    
                    
//回溯
                    selected[j]=false;
                    v[i]
=-1;
                }

            }
            
                        
        }

    }

    
    
private void gatherPermutationResult(int[] v){
        
for(int i=0;i<v.length;i++){
            
if(v[i]==-1){
                
return;
            }

        }

        pList.add(v.clone());
    }

    
    
private void doMatch(){
        
//初始化
        Combine[] items=new Combine[5];
        
for(int i=0;i<items.length;i++){
            items[i]
=new Combine();
            items[i].no
=NO[i];
        }

        
//准备排列组合
        readyPermutation(5);
        
//匹配
        assignCombine(items);    
    }

    
    
    
public static void main(String[] args) {
        
new EinsteinProblem().doMatch();
    }
    
}

 

执行输出

1 绿 挪威 咖啡 PALL MALL 鸟
2 蓝 德国 矿泉水 PRINCE 猫
3 红 英国 牛奶 混合烟 马
4 黄 丹麦 茶 DUNHILL 鱼
5 白 瑞典 啤酒 BLUE MASTER 狗


1 绿 挪威 咖啡 PALL MALL 鸟
2 蓝 德国 矿泉水 PRINCE 鱼
3 红 英国 牛奶 混合烟 马
4 黄 丹麦 茶 DUNHILL 猫
5 白 瑞典 啤酒 BLUE MASTER 狗


1 绿 挪威 咖啡 PALL MALL 鸟
2 蓝 德国 矿泉水 PRINCE 猫
3 白 瑞典 牛奶 混合烟 狗
4 红 英国 啤酒 BLUE MASTER 马
5 黄 丹麦 茶 DUNHILL 鱼


1 绿 挪威 咖啡 PALL MALL 鸟
2 蓝 德国 矿泉水 PRINCE 猫
3 白 瑞典 牛奶 混合烟 狗
4 黄 丹麦 茶 DUNHILL 鱼
5 红 英国 啤酒 BLUE MASTER 马


1 绿 挪威 咖啡 PALL MALL 鸟
2 蓝 德国 矿泉水 PRINCE 鱼
3 白 瑞典 牛奶 混合烟 狗
4 黄 丹麦 茶 DUNHILL 猫
5 红 英国 啤酒 BLUE MASTER 马


1 绿 挪威 咖啡 混合烟 鱼
2 蓝 德国 矿泉水 PRINCE 猫
3 黄 瑞典 牛奶 DUNHILL 狗
4 红 英国 啤酒 BLUE MASTER 马
5 白 丹麦 茶 PALL MALL 鸟


1 黄 挪威 矿泉水 DUNHILL 猫
2 蓝 丹麦 茶 混合烟 马
3 红 英国 牛奶 PALL MALL 鸟
4 绿 德国 咖啡 PRINCE 鱼
5 白 瑞典 啤酒 BLUE MASTER 狗


Matched count=7

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
爱因斯坦阶梯编程题是一个经典的编程问题,涉及到C语言的使用。现在,我将用300字来回答这个问题。 在爱因斯坦阶梯编程题中,我们需要根据一些条件来确定背包中不同物体的重量,以及物体之间的关系。根据题目的信息,我们可以得以下结论: 1. 有5个人,他们分别是:爱因斯坦、亚里士多德、阿基米德、笛卡尔、牛顿。他们的职业分别是:物理学家、哲学家、数学家、哲学家、物理学家。 2. 到达顶端之前,只有两个人可以站在阶梯上,并且总是站在爱因斯坦的前面。 3. 笛卡尔的重量比爱因斯坦的轻,但是比数学家的重量要重。 4. 物理学家的重量最重,他的身高比其他所有人都高。 根据以上信息,我们可以得以下答案: 1. 爱因斯坦是物理学家,且他站在阶梯中间,所以他是第三个上到顶端的人。 2. 由于爱因斯坦的前面只有两个人,所以在他前面的人只能是亚里士多德和阿基米德。 3. 笛卡尔的重量比爱因斯坦轻,但是比数学家重,所以他不能是第一个上到顶端的人。 4. 物理学家的重量最重,所以他不能是最轻的人。 综上所述,根据题目的条件,正确的答案是:亚里士多德、阿基米德、爱因斯坦、笛卡尔、牛顿。他们的职业分别是:哲学家、数学家、物理学家、哲学家、物理学家。 以上就是爱因斯坦阶梯编程题的回答。在实际编程中,我们可以使用C语言来实现相关逻辑,通过判断和比较来得到最终的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值