受约束的10人参赛问题

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名同学参赛者名单 比如LC D G J 


/**
	个人分析:
	暴力枚举,注意条件
	s[0] 1 2 3 4 5 6 7 8 9
	  A  B C D E F G H I J
	judge()用来判断条件
	func()用来生成各种组合情况
	
	自己编程出现的问题:
	1、func(),到达n==10才意味着生成了一种新的组合;
	2、题目条件转换成代码时,出现问题
	   比如:如果A参加,B也参加
	   		 if(!(A==1 && B==1))
				return false;
	   错误在于:这样写,意味着A必须参加
	   正解:老老实实按着题目翻译 
	   		 if(A==1)		//如果A参加
	   		 {
	   		 	if(B==0)	//而B不参加 
	   		 		return false;
			 } 
	 
*/	
#include <iostream>
using namespace std;
bool judge(int const *s)
{	
	//如果A参加,B也参加
	if(s[0]==1)
	{
		if(s[1]==0)
			return false;
	}
		
	//如果C不参加,D也不参加
	if(s[2]==0)
	{
		if(s[3]==1)
			return false;
	}
	
	//A和C中只能有一个人参加
	if(s[0]*s[2]==1)
		return false;
	
	//B和D中有且仅有一个人参加
	if(!((s[1]==1 && s[3]==0)||(s[1]==0 && s[3]==1)))
		return false;
		
	//D、E、F、G、H 中至少有2人参加
	int ans = 0;
	if(s[3]==1)
		ans++;
	if(s[4])
		ans++;
	if(s[5])
		ans++;
	if(s[6])
		ans++;
	if(s[7])
		ans++;
	if(ans<2)
		return false;
		
	//C和G或者都参加,或者都不参加
	if(!((s[2]==1&&s[6]==1)||(s[2]==0&&s[6]==0)))
		return false;
		
	//C、E、G、I中至多只能2人参加
	ans = 0;
	if(s[2]==1)
		ans++;
	if(s[4])
		ans++;
	if(s[6])
		ans++;
	if(s[8])
		ans++;
	if(ans>2)
		return false;
		
	//如果E参加,那么F和G也都参加
	if(s[4]==1)
	{
		if(s[5]==0 || s[6]==0)
			return false;
	}
		
	//如果F参加,G、H就不能参加
	if(s[5]==1)
	{
		if(s[6]==1 || s[7]==1)
			return false;
	} 
		
	//如果I、J都不参加,H必须参加
	if(s[8]==0 && s[9]==0)
	{
		if(s[7]==0)
			return false;
	} 

	return true;
}
void func(int *s,int n)
{	 
	if(n==10)
	{
		if(judge(s))
		{
			for(int i=0;i<=9;i++)
			{
				if(s[i]==1)
					cout<<char(i+'A')<<" ";
			}
			cout<<endl;
		}
	}
	else if(n>10)
		return;
	s[n] = 0;
	func(s,n+1);
	s[n] = 1;
	func(s,n+1);
}
int main()
{
	int s[10] = {0};
	func(s,0); 
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值