爱因斯坦的思考题

没怎么写过C代码, 请大家多多批评

这个也不是用程序实现功能, 主要是作为辅助判断的工具

题目来自这里: http://blog.csdn.net/orbit/article/details/6994575

没有细看原作者的解决方案....不过根据做这个题的过程, 有下面思路可以设计程序解决:

1. 设定一个肯定满足的解集(这里我们就是列出了所有的可能性)

2. 将提示进行抽象, 归纳为几种类型的过滤器

3. 轮询用过滤器循环检查, 直到运行一次所有过滤器不会对数据产生修改, 结束

此时就应该是最终结果了.

/** * author: selfimpr * mail: lgg860911@yahoo.com.cn * blog: http://blog.csdn.net/lgg201 * 问题描述: 5人, 住5间房. 5人不同国家, 5房不同颜色, 5人不同宠物, 5人不同饮品, 5人抽不同烟, 满足下面条件 * (1) 英国人住在红色的房子里; * (2) 瑞典人养狗作为宠物; * (3) 丹麦人喝茶; * (4) 绿房子紧挨着白房子,在白房子的左边; * (5) 绿房子的主人喝咖啡; * (6) 抽Pall Mall牌香烟的人养鸟; * (7) 黄色房子里的人抽Dunhill牌香烟; * (8) 住在中间那个房子里的人喝牛奶; * (9) 挪威人住在第一个房子里面; * (10) 抽Blends牌香烟的人和养猫的人相邻; * (11) 养马的人和抽Dunhill牌香烟的人相邻; * (12) 抽BlueMaster牌香烟的人和啤酒; * (13) 德国人抽Prince牌香烟; * (14) 挪威人和住在蓝房子的人相邻; * (15) 抽Blends牌香烟的人和喝矿泉水的人相邻。 * 结果: 初始化 +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | index | country | color | animal | drink | smoke | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | 0 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | 1 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | 2 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | 3 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ | 4 | red,green,white,yellow,blue | england,sweden,denmark,norway,germany | bird,cat,dog,fish,horse | tea,coffee,milk,beer,water | pall_mall,dunhill,blends,blue_master,prince | +----------+-----------------------------+---------------------------------------+----------------------------------------------------------------------------------------------------+ 结果分布 +----------+-----------+---------+--------+---------+-------------+ | index | country | color | animal | drink | smoke | +----------+-----------+---------+--------+---------+-------------+ | 0 | yellow | norway | cat | water | dunhill | +----------+-----------+---------+--------+---------+-------------+ | 1 | blue | denmark | horse | tea | blends | +----------+-----------+---------+--------+---------+-------------+ | 2 | red | england | bird | milk | pall_mall | +----------+-----------+---------+--------+---------+-------------+ | 3 | green | germany | fish | coffee | prince | +----------+-----------+---------+--------+---------+-------------+ | 4 | white | sweden | dog | beer | blue_master | +----------+-----------+---------+--------+---------+-------------+ * 思路: 初始假定5间房, 所有条件全部满足, 然后根据提示进行排除 * 实现: 目前程序只是一个辅助手段, 还是靠手动执行判断的 * 改进方案: 将15个条件抽象为过滤器, 逐遍扫描过滤器, 直到所有过滤器执行一轮不会使结果发生变化 */ #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #define HOUSE_SIZE 5 #define CONDITION_NUM 5 #define OUTPUT_FORMAT "%-10s|%-40s|%-40s|%-40s|%-40s|%-40s\n" const char *colors[] = {"red", "green", "white", "yellow", "blue"}; const char *countrys[] = {"england", "sweden", "denmark", "norway", "germany"}; const char *animals[] = {"bird", "cat", "dog", "fish", "horse"}; const char *drinks[] = {"tea", "coffee", "milk", "beer", "water"}; const char *smokes[] = {"pall_mall", "dunhill", "blends", "blue_master", "prince"}; struct house { int color[CONDITION_NUM + 1]; int country[CONDITION_NUM + 1]; int animal[CONDITION_NUM + 1]; int drink[CONDITION_NUM + 1]; int smoke[CONDITION_NUM + 1]; }; //数据的初始化/销毁/打印 struct house *houses_init(); void houses_dest(struct house *); void houses_show(struct house *, char *); void house_show(struct house *, int); void items_show(const char **, const int *, const char *); //数据处理 void items_remove(int *, ...); void item_remove(int *, int); void item_remain(int *, int); //提示信息 void split_tips(char *); void main(void) { struct house *houses; //初始化数据 houses = houses_init(); //展示初始化数据 houses_show(houses, "初始化"); //删除测试 //items_remove(houses->color, 1, 3, -1); //houses_show(houses, "删除测试"); //剩余测试 //item_remain(houses->country, 1); //houses_show(houses, "剩余测试"); //条件过滤 //挪威人在第一个房子 item_remain(houses[0].country, 3); item_remove(houses[1].country, 3); item_remove(houses[2].country, 3); item_remove(houses[3].country, 3); item_remove(houses[4].country, 3); //中间房子的喝牛奶 item_remove(houses[0].drink, 2); item_remove(houses[1].drink, 2); item_remain(houses[2].drink, 2); item_remove(houses[3].drink, 2); item_remove(houses[4].drink, 2); //挪威人和住在蓝房子的人相邻 item_remove(houses[0].color, 4); item_remain(houses[1].color, 4); item_remove(houses[2].color, 4); item_remove(houses[3].color, 4); item_remove(houses[4].color, 4); //绿色房子的主人喝咖啡 item_remove(houses[2].color, 1); //绿色房子紧挨着白房子, 在白房子的左边 item_remove(houses[0].color, 1); item_remain(houses[3].color, 1); item_remain(houses[4].color, 2); item_remove(houses[0].color, 2); item_remove(houses[2].color, 2); //挪威人在第一个房子 //英国人住在红色的房子 //只剩下0,2两个房子颜色不确定 item_remove(houses[0].color, 0); item_remain(houses[2].color, 0); item_remain(houses[2].country, 0); item_remove(houses[1].country, 0); item_remove(houses[3].country, 0); item_remove(houses[4].country, 0); //绿房子的主人喝咖啡 item_remove(houses[0].drink, 1); item_remove(houses[1].drink, 1); item_remove(houses[2].drink, 1); item_remain(houses[3].drink, 1); item_remove(houses[4].drink, 1); //黄色房子的主人抽Dunhill香烟 item_remain(houses[0].smoke, 1); item_remove(houses[1].smoke, 1); item_remove(houses[2].smoke, 1); item_remove(houses[3].smoke, 1); item_remove(houses[4].smoke, 1); //养马的人和抽Dunhill的人相邻 item_remove(houses[0].animal, 4); item_remain(houses[1].animal, 4); item_remove(houses[2].animal, 4); item_remove(houses[3].animal, 4); item_remove(houses[4].animal, 4); //丹麦人喝茶 item_remove(houses[3].country, 2); //抽Blends香烟的人和喝矿泉水的人相邻 item_remove(houses[4].smoke, 2); //抽BlueMaster香烟的人喝啤酒 item_remove(houses[2].smoke, 3); item_remove(houses[3].smoke, 3); item_remove(houses[0].drink, 3); //丹麦人喝茶 item_remain(houses[0].drink, 4); item_remove(houses[1].drink, 4); item_remove(houses[4].drink, 4); //抽Blends香烟的人和喝矿泉水的相邻 item_remain(houses[1].smoke, 2); item_remove(houses[2].smoke, 2); item_remove(houses[3].smoke, 2); item_remain(houses[4].smoke, 3); //德国人抽Prince item_remove(houses[2].smoke, 4); item_remain(houses[3].smoke, 4); item_remain(houses[3].country, 4); item_remove(houses[1].country, 4); item_remove(houses[4].country, 4); //抽BlueMaster香烟的人喝啤酒 item_remain(houses[4].drink, 3); item_remove(houses[1].drink, 3); //丹麦人喝茶 item_remain(houses[1].country, 2); item_remove(houses[4].country, 2); //抽PallMall香烟的人养鸟 item_remain(houses[2].animal, 0); item_remove(houses[0].animal, 0); item_remove(houses[3].animal, 0); item_remove(houses[4].animal, 0); //瑞典人养狗 item_remain(houses[4].animal, 2); item_remove(houses[0].animal, 2); item_remove(houses[3].animal, 2); //抽Blends香烟的和养猫的人相邻 item_remain(houses[0].animal, 1); item_remove(houses[3].animal, 1); houses_show(houses, "过滤后"); houses_dest(houses); } struct house *houses_init() { struct house *houses; int i = 0, j; houses = (struct house *)calloc(HOUSE_SIZE, sizeof(struct house)); for ( i = 0; i < HOUSE_SIZE; i ++ ) { for ( j = 0; j < CONDITION_NUM; j ++ ) { (houses + i)->color[j] = j; (houses + i)->country[j] = j; (houses + i)->animal[j] = j; (houses + i)->drink[j] = j; (houses + i)->smoke[j] = j; } (houses + i)->color[j] = -1; (houses + i)->country[j] = -1; (houses + i)->animal[j] = -1; (houses + i)->drink[j] = -1; (houses + i)->smoke[j] = -1; } return houses; } void houses_dest(struct house *houses) { free(houses); } void houses_show(struct house *houses, char *msg) { int i; if ( msg != NULL ) { split_tips(msg); } printf(OUTPUT_FORMAT, "index", "country", "color", "animal", "drink", "smoke"); for ( i = 0; i < HOUSE_SIZE; i ++ ) { house_show(houses + i, i); } printf("\n\n"); } void house_show(struct house *house, int index) { printf("%- 10d", index); items_show(colors, house->color, "|"); items_show(countrys, house->country, "|"); items_show(animals, house->animal, "|"); items_show(drinks, house->drink, "|"); items_show(smokes, house->smoke, "|"); printf("\n"); } void items_show(const char **names, const int *items, const char *msg) { if ( msg != NULL ) printf("%s", msg); int i; char *tmp = malloc(sizeof(char) * 1024); char *tmp_s = tmp; for ( i = 0; *(items + i) != -1; i ++ ) { tmp += sprintf(tmp, "%s", *(names + *(items + i))); if ( *(items + i + 1) != -1 ) tmp += sprintf(tmp, ","); } printf("%-40s", tmp_s); } void items_remove(int *items, ...) { int value; va_list va; va_start(va, items); while ( (value = va_arg(va, int)) != -1 ) { item_remove(items, value); } va_end(va); } void item_remove(int *items, int item) { int i; for ( i = 0; *(items + i) != -1; i ++ ) { if ( item == *(items + i ) ) break; } for ( ; *(items + i ) != -1; i ++ ) { *(items + i) = *(items + i + 1); } } void item_remain(int *items, int item) { int i; for ( i = 0; *(items + i) != -1; ) { if ( item != *(items + i) ) item_remove(items, *(items + i)); else i ++; } } void split_tips(char *msg) { printf("------------------------------------------%s---------------------------------------\n", msg); }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值