题目是这样的,有五个不同颜色的房间排成一排,每个房间里分别住着一个不同国籍的人,每个人都喝一种特定品牌的饮料,抽一种特定品牌的烟,养一种宠物。没有任意两个人的任意属性值是相同的。问:是谁在养鱼? 下面是给出的15条线索。
- 英国人住在红色的房子里;
- 瑞典人养狗作为宠物;
- 丹麦人喝茶;
- 绿房子紧挨着白房子,在白房子的左边;
- 绿房子的主人喝咖啡;
- 抽Pall Mall牌香烟的人养鸟;
- 黄色房子里的人抽Dunhill牌香烟;
- 住在中间那个房子里的人喝牛奶;
- 挪威人住在第一个房子里面;
- 抽Blends牌香烟的人和养猫的人相邻;
- 养马的人和抽Dunhill牌香烟的人相邻;
- 抽BlueMaster牌香烟的人喝啤酒;
- 德国人抽Prince牌香烟;
- 挪威人和住在蓝房子的人相邻;
- 抽Blends牌香烟的人和喝矿泉水的人相邻。
求解思路:多维穷举遍历每个属性值组成的“人”,并用条件中的个体条件(条件中只包含了一个人)来筛选,将其加入对应房子的候选人列表中。然后对5个房子的候选人列表进行多重遍历,并用事关两个人的条件(比如条件10、11)进行筛选,而且选中的5个人的属性值不能重复,最后输出正确答案。代码如下:
import java.util.Vector;public class Einstein { static class Person { final COLOR color; final NATION nation; final DRINK drink; final PET pet; final CIGARETTE cigarette; final int index; //在几号房子 public Person(COLOR color, NATION nation, DRINK drink, PET pet, CIGARETTE cigarette, int index) { this.color = color; this.nation = nation; this.drink = drink; this.pet = pet; this.cigarette = cigarette; this.index = index; } @Override public String toString() { return "Person{" + "color=" + color + ", nation=" + nation + ", drink=" + drink + ", pet=" + pet + ", cigarette=" + cigarette + ", index=" + index + '}'; } } enum COLOR {Yellow, Blue, Red, Green, White} enum NATION {Norway, Denmark, England, Germany, Sweden} enum DRINK {Water, Tea, Milk, Coffee, Beer} enum PET {Cat, Horse, Bird, Fish, Dog} enum CIGARETTE {Dunhill, Blends, PallMall, Prince, BlueMaster} boolean test1(final Person person) { return (person.color == COLOR.Red && person.nation == NATION.England) || (person.color != COLOR.Red && person.nation != NATION.England); } boolean test2(final Person person) { return (person.nation == NATION.Sweden && person.pet == PET.Dog) || (person.nation != NATION.Sweden && person.pet != PET.Dog); } boolean test3(final Person person) { return (person.nation == NATION.Denmark && person.drink == DRINK.Tea) || (person.nation != NATION.Denmark && person.drink != DRINK.Tea); } boolean test5(final Person person) { return (person.color == COLOR.Green && person.drink == DRINK.Coffee) || (person.color != COLOR.Green && person.drink != DRINK.Coffee); } boolean test6(final Person person) { return (person.cigarette == CIGARETTE.PallMall && person.pet == PET.Bird) || (person.cigarette != CIGARETTE.PallMall && person.pet != PET.Bird); } boolean test7(final Person person) { return (person.color == COLOR.Yellow && person.cigarette == CIGARETTE.Dunhill) || (person.color != COLOR.Yellow && person.cigarette != CIGARETTE.Dunhill); } boolean test8(final Person person) { return (person.index == 2 && person.drink == DRINK.Milk) || (person.index != 2 && person.drink != DRINK.Milk); } boolean test9(final Person person) { return (person.index == 0 && person.nation == NATION.Norway) || (person.index != 0 && person.nation != NATION.Norway); } boolean test12(final Person person) { return (person.cigarette == CIGARETTE.BlueMaster && person.drink == DRINK.Beer) || (person.cigarette != CIGARETTE.BlueMaster && person.drink != DRINK.Beer); } boolean test13(final Person person) { return (person.nation == NATION.Germany && person.cigarette == CIGARETTE.Prince) || (person.nation != NATION.Germany && person.cigarette != CIGARETTE.Prince); } boolean test14(final Person person) { return (person.color == COLOR.Blue && person.index == 1) || (person.color != COLOR.Blue && person.index != 1); } private Vectorhouse0 = new Vector<>(); private Vector house1 = new Vector<>(); private Vector house2 = new Vector<>(); private Vector house3 = new Vector<>(); private Vector house4 = new Vector<>(); public void search() { //先构造满足个体条件的人,然后加入不同的房子里,再对房子里面的人进行循环 for (COLOR color : COLOR.values()) { for (NATION nation : NATION.values()) { for (DRINK drink : DRINK.values()) { for (PET pet : PET.values()) { for (CIGARETTE cigarette : CIGARETTE.values()) { for (int index = 0; index < 5; index++) { final Person person = new Person(color, nation, drink, pet, cigarette, index); //如果这个人满足个体条件,则加入对应的房子 if (test1(person) && test2(person) && test3(person) && test5(person) && test6(person) && test7(person) && test8(person) && test9(person) && test12(person) && test13(person) && test14(person)) { switch (person.index) { case 0: house0.add(person); break; case 1: house1.add(person); break; case 2: house2.add(person); break; case 3: house3.add(person); break; case 4: house4.add(person); break; } } } } } } } } //对5个房子里面的人进行循环 for (Person person0 : house0) { for (Person person1 : house1) { for (Person person2 : house2) { for (Person person3 : house3) { for (Person person4 : house4) { final Person[] people = {person0, person1, person2, person3, person4}; if (test4(people) && test10(people) && test11(people) && test15(people) && isDistinct(people)) { //找到了正确结果并输出 for (Person person : people) { System.out.println(person); } } } } } } } } //判断这组人是否有状态重复。不重复的情况下应该每种属性的值只有一个人有 private boolean isDistinct(final Person... people) { boolean[] colors = new boolean[5]; boolean[] nations = new boolean[5]; boolean[] drinks = new boolean[5]; boolean[] pets = new boolean[5]; boolean[] cigarettes = new boolean[5]; for (int i = 0; i < 5; i++) { colors[people[i].color.ordinal()] = true; nations[people[i].nation.ordinal()] = true; drinks[people[i].drink.ordinal()] = true; pets[people[i].pet.ordinal()] = true; cigarettes[people[i].cigarette.ordinal()] = true; } boolean result = true; for (int i = 0; i < 5; i++) { result &= (colors[i] && nations[i] && drinks[i] && pets[i] && cigarettes[i]); } return result; } private boolean test4(final Person... people) { int green = 0; int white = 0; for (Person person : people) { if (person.color == COLOR.Green) green = person.index; if (person.color == COLOR.White) white = person.index; } return green + 1 == white; } private boolean test10(final Person... people) { int blends = 0; int cat = 0; for (Person person : people) { if (person.cigarette == CIGARETTE.Blends) blends = person.index; if (person.pet == PET.Cat) cat = person.index; } return (blends + 1 == cat) || (blends - 1 == cat); } private boolean test11(final Person... people) { int horse = 0; int dunhill = 0; for (Person person : people) { if (person.cigarette == CIGARETTE.Dunhill) dunhill = person.index; if (person.pet == PET.Horse) horse = person.index; } return (horse + 1 == dunhill) || (horse - 1 == dunhill); } private boolean test15(final Person... people) { int blends = 0; int water = 0; for (Person person : people) { if (person.cigarette == CIGARETTE.Blends) blends = person.index; if (person.drink == DRINK.Water) water = person.index; } return (blends + 1 == water) || (blends - 1 == water); } public static void main(String[] args) { new Einstein().search(); }}复制代码
注:喜欢的朋友可以点赞关注,一起学习进步。