蓝桥杯(受约束的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也都参加。

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 //该题的关键还在于如何枚举10个数,可以10重for循环,也可以类似素数环进行回溯,或者二进制枚举 
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int vis[11] = {0};
 7 
 8 //vis若是bool 变不可写成两数相加减 
 9 bool judge()
10 {
11      //a推出(蕴含)b,等价于(非a或b);或者a ==1&&b==1||a==0,等价于a==0||b==1,此次用到了短路表达式的性质 
12      bool t1 = (vis[0]== 0||vis[1] == 1);
13      //类似第一个;或者c==0&&d==0||c=1 
14      bool t2 =( vis[2] == 1||vis[3] == 0);
15      //从第四个条件可以看出这个包含都不参加的情况,等价于都不参加或者只参加一个人,反面是两个人都参加,再取反 !(a==1&&c==1)等价于a==0||c==0,转化为a+c<=1
16      bool t3 = ((vis[0] + vis[2])<=1);//或者等于0 
17      //反面是同时参加或者同时不参加,再取反!(b==d),等价于b+d ==1
18      bool t4 = (vis[1] + vis[3]==1);
19      bool t5 = ((vis[3] + vis[4] + vis[5] + vis[6] + vis[7]) >=2);
20      //c==g,可化为就、相加为0或者2 
21      bool t6 = (vis[2] == vis[6]);
22      bool t7 = ((vis[2]+vis[4]+vis[6]+vis[8])<=2);
23      //类似第一个 
24      bool t8 = (vis[4] == 0||(vis[5] + vis[6] == 2));
25      bool t9 = vis[5]==0||(vis[6]+vis[7]==0);
26      //(i ==0&&j==0)&&h==1||(ij至少一人参加),等价于(i==1||j==1)||h==1 
27      bool t10 = (vis[8]+vis[9]>0)||vis[7]==1;
28      return t1&&t2&&t3&&t4&&t5&&t6&&t7&&t8&&t9&&t10;
29 }
30 void print()
31 {
32      int i,j,k;
33      for(i=0; i<10; i++)
34           if(vis[i]>0)//若vis是bool,所以不可写成vis[i]>0 
35           {
36                char ch = i + 'A';
37                cout<<ch<<" ";
38           }
39 }
40 int main()
41 {
42      int i,j,k;
43      //二进制枚举比递归回溯好理解 
44      //二进制枚举,两数的与或疑惑分别表示集合的交并对称差 
45      int total = 0;//
46      memset(vis,0,sizeof(vis));
47      while(total<1024)//用total的前十位表示参加状态,1024并不是来自1<<10,而是十个1表示(1<<10-1) 
48      {
49           total++;//不可能全都不参加,所以先自增了
50           for(i=0; i<10; i++)//用total的底10为表示状态,或者total按求余法求的底十位 
51           {
52                int temp = (1<<i);
53                int tag = (temp & total);
            // 也可以用临时变量先存储total,然后total每次右移,与1求与,刘汝佳课本上不是这种方法 
54 if(tag) 55 { 56 //cout<<"*******"<<endl; 57 vis[i] = 1;//把赋值号写成了等号 58 } 59 else 60 vis[i] = 0; 61 } 62 bool flag = judge(); 63 //cout<<flag<<endl; 64 if(flag) 65 { 66 print(); 67 cout<<endl; 68 } 69 } 70 cout<<"----"<<endl; //结果没输出,看看是否执行到了这一步 71 cout<<endl; 72 while(1); 73 return 0; 74 } 75 //把给的例子带入发现正确,说明judge函数没问题,那么就是while循环有问题了 ,结果发现vis全为0 ,再以发现把赋值号写成了等号 76 77
 1 //递归回溯 
 2 #include <iostream>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 int vis[11] = {0};
 7 
 8 //vis若是bool 变不可写成两数相加减 
 9 bool judge()
10 {
11      //a推出(蕴含)b,等价于(非a或b);或者a ==1&&b==1||a==0,等价于a==0||b==1,此次用到了短路表达式的性质 
12      bool t1 = (vis[0]== 0||vis[1] == 1);
13      //类似第一个;或者c==0&&d==0||c=1 
14      bool t2 =( vis[2] == 1||vis[3] == 0);
15      //从第四个条件可以看出这个包含都不参加的情况,等价于都不参加或者只参加一个人,反面是两个人都参加,再取反 !(a==1&&c==1)等价于a==0||c==0,转化为a+c<=1
16      bool t3 = ((vis[0] + vis[2])<=1);//或者等于0 
17      //反面是同时参加或者同时不参加,再取反!(b==d),等价于b+d ==1
18      bool t4 = (vis[1] + vis[3]==1);
19      bool t5 = ((vis[3] + vis[4] + vis[5] + vis[6] + vis[7]) >=2);
20      //c==g,可化为就、相加为0或者2 
21      bool t6 = (vis[2] == vis[6]);
22      bool t7 = ((vis[2]+vis[4]+vis[6]+vis[8])<=2);
23      //类似第一个 
24      bool t8 = (vis[4] == 0||(vis[5] + vis[6] == 2));
25      bool t9 = vis[5]==0||(vis[6]+vis[7]==0);
26      //(i ==0&&j==0)&&h==1||(ij至少一人参加),等价于(i==1||j==1)||h==1 
27      bool t10 = (vis[8]+vis[9]>0)||vis[7]==1;
28      return t1&&t2&&t3&&t4&&t5&&t6&&t7&&t8&&t9&&t10;
29 }
30 
31 void print()
32 {
33      int i,j,k;
34      for(i=0; i<10; i++)
35           if(vis[i]>0)//若vis是bool,所以不可写成vis[i]>0 
36           {
37                char ch = i + 'A';
38                cout<<ch<<" ";
39           }
40 }
41 
42 void dfs(int n)
43 {
44      if(n>=10)
45      {
46           if(judge())
47           {
48                print();
49                cout<<endl;
50           }
51           return ;
52      }
53      vis[n] = 0;
54      dfs(n+1);
55      vis[n] = 1;
56      dfs(n+1);
57 }
58 
59 int main()
60 {
61      int i,j,k;
62      int total = 0;//
63      memset(vis,0,sizeof(vis));
64      dfs(0);
65      cout<<"----"<<endl; //结果没输出,看看是否执行到了这一步      
66      cout<<endl;
67      while(1);
68      return 0;
69 }
70 //把给的例子带入发现正确,说明judge函数没问题,那么就是while循环有问题了 ,结果发现vis全为0 ,再以发现把赋值号写成了等号 
71      
72      


看视频加上写代码和注释共约4个小时,还是相当有成就感的。

目录
相关文章
|
13天前
|
内存技术
|
2月前
|
测试技术 C语言
第十四届蓝桥杯B组第一期模拟题
第十四届蓝桥杯B组第一期模拟题
32 0
|
9月前
|
测试技术
【蓝桥杯冲刺】蓝桥杯13届省赛C++b组真题-A~E题
【蓝桥杯冲刺】蓝桥杯13届省赛C++b组真题-A~E题
114 0
|
11月前
【newcode】牛牛组队竞赛
【newcode】牛牛组队竞赛
75 0
|
11月前
|
算法 C语言 C++
第十四届蓝桥杯C/C++程序设计大学B组(参赛经历总结)
第十四届蓝桥杯C/C++程序设计大学B组(参赛经历总结)(蒟蒻的流泪经历)
132 0
|
存储 人工智能 算法
【蓝桥杯集训·最后一次周赛】AcWing 第 97 场周赛
文章目录 第一题 AcWing 4944. 热身计算 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第二题 AcWing 4945. 比大小 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第三题 AcWing 4946. 叶子节点 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
98 0
|
JavaScript BI
【蓝桥杯集训·周赛】AcWing 第96场周赛
文章目录 第一题 AcWing 4876. 完美数 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第二题 AcWing 4877. 最大价值 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解 第三题 AcWing 4878. 维护数组 一、题目 1、原题链接 2、题目描述 二、解题报告 1、思路分析 2、时间复杂度 3、代码详解
64 0