A、B、C、D、E、F、G、H、I、J 共10名学生有可能参加本次计算机竞赛,也可能不参加。因为某种原因,他们是否参赛受到下列条件的约束:
1. 如果A参加,B也参加;
2. 如果C不参加,D也不参加;
3. A和C中只能有一个人参加;
4. B和D中有且仅有一个人参加;
5. D、E、F、G、H 中至少有2人参加;
6. C和G或者都参加,或者都不参加;
7. C、E、G、I中至多只能2人参加
8. 如果E参加,那么F和G也都参加。
9. 如果F参加,G、H就不能参加
10. 如果I、J都不参加,H必须参加
请编程根据这些条件判断这10名同学中参赛者名单。如果有多种可能,则输出所有的可能情况。每种情况占一行。参赛同学按字母升序排列,用空格分隔。
比如:
C D G J
就是一种可能的情况。
多种情况的前后顺序不重要
技巧: 参加为1,不参加为0,不用boolean类型
3 if(a+c<=1)
4 if(b+d==1)
离散数学中的逻辑推理题,看到题的第一反应是这些同学毛病真多。。。。。
10个判断条件,不过这道题还是挺有意思的。
比如 8. 如果E参加,那么F和G也都参加。
9. 如果F参加,G、H就不能参加
很矛盾的逻辑,E参加了,就是有问题的,所以E不可能参加
/* A B C D E F G H I J 1 2 3 4 5 6 7 8 9 10 */ #include <stdio.h> int a[11]; void judge() { if((a[1]+a[2]==2)||!a[1]) { if((a[3]+a[4]==0)||a[3]) { if(a[1]+a[3]<=1) { if(a[2]+a[4]==1) { if(a[4]+a[5]+a[6]+a[7]+a[8]>=2) { if((a[3]+a[7]==2)||(a[3]+a[7]==0)) { if(a[3]+a[5]+a[7]+a[9]<=2) { if((a[5]+a[6]+a[7]==3)||(!a[5])) { if((a[6]&&a[6]+a[7]+a[8]==1)||(!a[6])) { if((a[9]+a[10]==0&&a[8])||(a[9]+a[10]>=1)) { int i; for(i=1; i<=10; i++) if(a[i]) printf("%c ",i+64 ); printf("\n"); } } } } } } } } } } } void dfs(int k) { int i; if(k==11) { judge(); return; } for(i=0; i<=1; i++) { a[k]=i; dfs(k+1); } } int main() { dfs(1); return 0; }
看到有个帖子专门讨论这道题,然后也有段我觉得很精简的代码,贴出来和有机会看到的大佬分享下。
#include <stdio.h> void show(int *x); int judege(int *x); void curision(int *x, int n); int main() { int x[10]; curision(x,0); return 0; } void show(int *x) { for(int i=0; i<10; i++) if(x[i]>0) printf("%c ", i+'A'); putchar(10); } int judge(int *x) { int t1= x[0]==0 || x[1]==1; int t2= x[2]==1 || x[3]==0; int t3= x[0] + x[2] <= 1; int t4= x[1] + x[3] == 1; int t5= x[3] + x[4] + x[5] + x[6] + x[7] >=2; int t6= (x[2]+x[6]==2) || (x[2]+x[6]==0); int t7= x[2]+x[4]+x[6]+x[8] <= 2; int t8= x[4]==0 || (x[5] + x[6]==2); int t9= x[5]==0 || (x[6] + x[7]==0); int t10= (x[8]+x[9]>0) || x[7]==1; return t1 && t2 && t3 && t3 && t4 && t5 && t6 && t7 && t8 && t9 && t10; } void curision(int *x, int n) { if(n>=10) { if(judge(x)) show(x); return; } x[n]=0; curision(x,n+1); x[n]=1; curision(x,n+1); }