爱因斯坦的思考题

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

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

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

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

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

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

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

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

/**
 *	author: selfimpr
 *	mail: [email protected]
 *	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);
}


你可能感兴趣的:(struct,测试,Blog,null,output,colors)