问题描述

某参观团按以下限制条件从A,B,C,D,E五个地方中选定若干参观点:
(1)如果去A地,则必须去B地
(2)DE只能去一个
(3)CB只能去一个
(4)CD要么都去要么都不去
(5)若去E则必须去AD
问该参观团能去哪几个地方?

分析

这道题看起来挺复杂的,应该怎么处理呢?每个地点两种状态,去或者不去,可以对应0和1这两个数值。使用a,b,c,d,e五个变量分别表示去这五个地点的状态。那么便可以将五个限制条件表达式列举出来。
(1)如果去A地,则必须去B地:A、B都去,或者不去A,B随便,表达式为:(a&&b)||(!a)
(2)DE只能去一个:d||e 或者d+e==1
(3)CB只能去一个:b||c或者b+c==1
(4)CD要么都去要么都不去:(c&&d)||(!c&&!d) 或者c+d ==2||c+d==0
(5)若去E则必须去AD:和(1)相似,(e&&a&&d)||!e
然后这五个条件需要同时满足。因此这五个表达式之间是“与”的关系。
然后尝试对a,b,c,d,e五个变量分别赋值,列举出所有情况,如果满足了条件便进行输出,如此便可得到所有可能的旅游方案。

源程序

C语言

  1. #include<stdio.h>
  2. int main()
  3. {
  4. int a,b,c,d,e;
  5. //对五个变量的所有值进行穷举赋值
  6. for(a=0;a<=1;a++)
  7. for(b=0;b<=1;b++)
  8. for(c=0;c<=1;c++)
  9. for(d=0;d<=1;d++)
  10. for(e=0;e<=1;e++)
  11. //满足限制条件时进行输出
  12. if(((a&&b)||(!a))&&(d+e==1)&&(b+c==1)&&(c+d ==2||c+d==0)&&((e&&a&&d)||!e))
  13. {
  14. printf("%d %d %d %d %d",a,b,c,d,e);
  15. }
  16. return 0;
  17. }

输出结果为:0 0 1 1 0,表示只能同时去C、D参观,其他地点不去,这一种方案。

python

  1. R = range(0,2)
  2. for a in R:
  3. for b in R:
  4. for c in R:
  5. for d in R:
  6. for e in R:
  7. require = ((a and b) or (not a)) and (d+e==1) and \
  8. (b+c==1) and (c+d ==2 or c+d==0) and ((e and a and d)or (not e))
  9. if require:
  10. print(a,b,c,d,e)

注意C语言和python逻辑运算符的不同。C语言可以使用“符号”,python使用“单词”。

拓展:小偷是谁

https://blog.csdn.net/weixin_41357720/article/details/79035668

问题描述

已知A,B,C,D中有一人是小偷,每个人不说真话便说的是假话
A: B没有偷,是D偷的
B : 我没有偷,是C偷的
C : A没有偷,是B偷的
D : 我没有偷

分析

这道题目看起来要更复杂一点,因为每个人说的话可能是真的也可能是假的,表达式该怎么表达呢?
事实上,只需要列举每个人说话的正反面就可以了。比如对A,真话是b=0,d=1,假话是b=1,d=0,总结一下就是b+d=1
类似的,每个条件可以表达为:
b+d==1;b+c==1;a+b==1;a+b+c+d==1

代码实现

python

  1. R = [0,1]
  2. for a in R:
  3. for b in R:
  4. for c in R:
  5. for d in R:
  6. require = b+d==1 and b+c==1 and a+b==1 and a+b+c+d==1
  7. if require:
  8. print(a,b,c,d)
  9. '''
  10. 输出结果为
  11. 0 1 0 0
  12. '''

因此是B为小偷