蓝桥杯 逻辑推断 DFS+n个if


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;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值