A、B、C、D、E、F、G、H、I、J
0 1 2 3 4 5 6 7 8 9
共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
就是一种可能的情况。
多种情况的前后顺序不重要
正如题目描述的那样,本题的核心就是逻辑判断,当然,判断之前我们先要把各种情况枚举出来,我想没有人会想用十重循环的,所以,当然还是使用递归的方法,在递归函数中,设置一个pos来表示当前枚举到第几个人的参加状态了,如果当枚举到第十一个人的时候(pos==10),很明显就是递归出口,然后我们对枚举出的结果,也就是每个人的参加状态进行逻辑判断,在判断的过程中,找一个事件不成立的情况是一个比较清晰快捷的方法,下面对每一个条件进行分析:
1. 如果A参加,B也参加;//A参加,并且B没参加
2. 如果C不参加,D也不参加;//C不参加,并且D参加了
3. A和C中只能有一个人参加;//A和C两个人都参加了
4. B和D中有且仅有一个人参加;//B和D的参加状态相同
5. D、E、F、G、H 中至少有2人参加;//参加的人数小于2
6. C和G或者都参加,或者都不参加;C和G参加的状态不同
7. C、E、G、I中至多只能2人参加 //参加的人数大于2
8. 如果E参加,那么F和G也都参加。//E参加了,并且F和G中存在没参加的
9. 如果F参加,G、H就不能参加 //F参加了,并且G和H中存在参加的
10. 如果I、J都不参加,H必须参加 //I和J都没参加,并且H也没参加
在判断函数中,凡是不满足的,直接return false,最后return true就可以了
#include<iostream>
#include<memory.h>
#include<stdio.h>
using namespace std;
bool join[10];
bool judge()
{
if(join[0]==1&&join[1]==0)
return false;
if(join[2]==0&&join[3]==1)
return false;
if(join[0]==1&&join[2]==1)
return false;
if(join[1]==join[3])
return false;
int count=0;
for(int i=3;i<=7;i++)
{
if(join[i]==1)
count++;
}
if(count<2)
return false;
if(join[2]!=join[6])
return false;
count=0;
for(int i=2;i<=8;i=i+2)
{
if(join[i]==1)
count++;
}
if(count>2)
return false;
if(join[4]==1)
{
if(join[5]==0||join[6]==0)
return false;
}
if(join[5]==1)
{
if(join[6]==1||join[7]==1)
return false;
}
if(join[8]==0&&join[9]==0)
{
if(join[7]==0)
return false;
}
return true;
}
void showResult()
{
for(int i=0;i<10;i++)
{
if(join[i]==1)
cout<<(char)(i+'A')<<' ';
}
cout<<endl;
}
void search(int pos)
{
if(pos==10)
{
if(judge())
showResult();
return;
}
for(int i=0;i<=1;i++)
{
join[pos]=i;
search(pos+1);
}
}
int main()
{
memset(join,false,sizeof(join));
search(0);
return 0;
}