第1个回答 2010-08-19
最简单的解法,把这个当做排列组合问题。然后把所有的排列组合结果带入到1-6这6个条件中进行检验。最后把满足所有条件的组合结果输出即可。
把四人姓的代码储存在A[3]中 (用代码方便运算并节约空间,值全用int,按格兰德、白思特、弗罗斯特和达特顺序为0-3)
四人名的代码储存在B[3]中 (莎莉=0,罗达=1,特雷西=2,万达=3)
树苗种类代码储存在C[3]中 (枫树=0,灰树=1,樱桃=2,云杉=3)
同理,院子位置代码D[3], (花园=0,院子前=1,院子后=2,天井=3)
种树日子E[3] (星期一=0,星期三=1,星期四=2,星期五=3)
排列组合代码自行解决下,假设每次生成结果用X数组储存,X[0]代表格兰德,X[1]代表白思特……,X数组的每个元素结构如下:
struct choice{
int b;
int c;
int d;
int e;
};
自己写个函数int find(X,arg1,arg2,arg3)
X为数组指针
arg1为指定已知条件,arg3为指定已知条件的值,arg2为指定返回条件,返回值为arg2指定的返回项。
arg1和arg2的值为0、1、2、3,4分别代表姓、名、树苗种类、位置、日期五个属性。
举例来说, s = find(X,2,3,2);这句话的含义就是找到X数组里树苗种类为樱桃的那条记录,返回它的栽种位置,返回值写入s中。
然后编写6条件判断:
1.姓弗罗斯特的人星期一种树;把树苗重在院子花园里的人是星期三种树;万达星期四种树;种枫树的人星期五种树。
(X[2].d == E[0])&&(find(X,3,4,0) == E[1]) &&(find(X,1,4,3) == E[2]) && (find(X,2,4,0) == E[3] )
2.特雷西在姓达特的人之前种树,在种灰树的那个人之后种树。
int temp = find(X,1,4,2)
(temp < find(X,0,4,3) )&&(temp > find(X,2,4,1))
3.姓白思特的那个人把自己的树重在了院子前面,她并不叫莎莉,也没有在星期五种树。
(find(X,0,1,1) != B[0] ) && ( find(X,0,4,1) != E[3])
4.罗达并没有在星期一种树。
find(X,1,4,1) != E[0]
5.姓格兰德的人种树的时间比把树重在院子后面的人要早;罗达并没有种樱桃树。
(find(X,0,4,0) < find(X,3,4,2))&&( find(X,1,2,1) != C[2])
6、万达并不姓弗罗斯特,没有把她的云杉树种到天井里。
(find(X,1,0,3) != A[2])&&(find(X,1,2,3) == C[3])&&(find(X,1,3,3) != D[3])
当然这里还可以简化一下,让万达和云杉这两个元素绑定起来。或者改进下数据结构比如用链表代替数组,如果题目扩充也能稍做调整就可以完成运算。不过大致的思路就是这样了。
有不懂的地方再交流。
第3个回答 2010-08-21
这种题可以不用编程,有更好的方法.
先想想出题人会怎样出题,他不太可能把它们的逻辑关系在脑子里记得那么清楚.
我猜他是用表格他们的逻辑关系表示出来.然后再给我们列出条件.
所以,你也可以办他们列成表格,先随便列出第一行,类如先列出四个人的姓名.
A,B,C,D
再根据给出的条件对应给下面添加他们的逻辑关系,就可以很快搞定了.
绝对原创.
本人几年前就用此法做出一道比楼主的问题更复杂的问题.