解题思路:
(1)整体思路:
首先定义A,B,C,D,E,F六个整型变量,规定去等于1 不去等于0;
假设没有派遣条件,共有2^6种派遣方式;
我们遍历这2^6种派遣方式,从符合题目所给条件的所有可行解中,输出最优解;
(定义A1,B1,C1,D1,E1,F1记录最优解;)
(得到最优解:定义一个派遣人数:numpeople=0,若可行解A+B+C+D+E+F(去的人数)大于numpeople,则更新最优解;)
(2)如何符合题目条件:
首先解析题目条件:
(解析过程,是离散数学上面的知识,一般没学也能理解)
同时满足下面6个限制条件的派遣情况,即是可行解;
1)A和B两人中至少去一人; (1.要么A,B都去; 2.要么A去,B不去; 3.要么A不去,B去)
(A==1&&B==1 || A==1&&B==0 || A==0&&B==1)
2)A和D不能一起去; (1.A去,D不去; 2.A不去,D去; 3.A,D都不去)(注意:此条件,和条件五是不同的)
(A==1&&D==0 || A==0&&D==1 || A==0&&D==0)
3)A、E和F三人中要派两人去; (1.A E去,F不去; 2.A F去,E不去; 3.A不去,E F去;)
(A==1&&E==1&&F==0 || A==1&&E==0&&F==1 || A==0&&E==1&&F==1)
4)B和C都去或都不去; (1.B去,C去; 2.B不去,C不去)
(B==0&&C==0 || B==1&&C==1)
5)C和D两人中去一个; (1.C去,D不去; 2.C不去,D去)
(C==1&&D==0 || C==0&&D==1)
6)若D不去,则E也不去;(1.D不去,E不去; 2.D去,E不去; 3.D去,E去)(“若”字的出现还有其它情况,所以是这样)
(D==0&&E==0 || D==1&&E==0 || D==1&&E==1)
注意事项:
注意条件2,与条件5之间的差别;以及条件6不是简单的一个条件;
接下来解释为什么,依照题目所给条件,无论怎么派遣,都只有一种派遣方法成立:
我们根据:1)A和B两人中至少去一人;这个已经定死的条件来推可行解:
(1):若A去,B不去:根据条件2,得到D不能去,再根据条件5,得到C要去,再看条件4 得到B要去;与开始B不去矛盾,无法得到解;
(2):若A不去,B去:根据条件4,得到C去,再根据条件5,得到D不去,再根据条件6,得到E不去,再看条件3,A,E,F中,必须去两个人,和之前A不去,E不去,矛盾,无法得到解;
(3):A去,B去,一定成立,这是最后一种方案,否则没有一种可行的派遣方案;(这个就不推了)
综上题目所给条件,只能推出一种派遣方案;这就是为什么,有的程序没有找最优解,直接输出过程中的可行解也是正确的原因。
下面代码中,加上了可行解的输出函数:outputKEXING(),和数字输出:printf("%d %d %d %d %d %d\n",A,B,C,D,E,F);可自行验证;
得到如图:
中间的A,B,C,F,和它后面的1 1 1 0 0 1;即是可行解;
最后一行的A,B,C,F,是最优解输出;
参考代码:
#include<stdio.h> int A,B,C,D,E,F; int A1,B1,C1,D1,E1,F1; int numpeople=0; void array(); void outputKEXING(); void outputZUIYOU(); /*--------------------------------------------*/ int main() { /*-------------------------------------------*/ for(int a=0;a<2;a++) { A=a; for(int b=0;b<2;b++) { B=b; for(int c=0;c<2;c++) { C=c; for(int d=0;d<2;d++) { D=d; for(int e=0;e<2;e++) { E=e; for(int f=0;f<2;f++) { F=f; array(); /*printf("%d %d %d %d %d %d\n",A,B,C,D,E,F);*/ //输出过程 } } } } } } outputZUIYOU(); return 0; } /*==========================================================*/ void array() { if((A==1&&B==1 || A==1&&B==0 || A==0&&B==1)&&(A==1&&D==0 || A==0&&D==1 || A==0&&D==0)&&(A==1&&E==1&&F==0 || A==1&&E==0&&F==1 || A==0&&E==1&&F==1)&&(B==0&&C==0 || B==1&&C==1)&&(C==1&&D==0 || C==0&&D==1)&&(D==0&&E==0 || D==1&&E==0 || D==1&&E==1)) { if(numpeople<(A+B+C+D+E+F)) { numpeople=A+B+C+D+E+F; A1=A;B1=B;C1=C;D1=D;E1=E;F1=F; } /*outputKEXING();*/ //输出可行解 } } /*==========================================================*/ void outputKEXING() { if(A==1) printf("A,"); if(B==1) printf("B,"); if(C==1) printf("C,"); if(D==1) printf("D,"); if(E==1) printf("E,"); if(F==1) printf("F,"); printf("\n"); } /*==========================================================*/ void outputZUIYOU() { if(A1==1) printf("A,"); if(B1==1) printf("B,"); if(C1==1) printf("C,"); if(D1==1) printf("D,"); if(E1==1) printf("E,"); if(F1==1) printf("F,"); }
0.0分
55 人评分
把它当成一个六位二进制数 #include<stdio.h> int main(void){ char member[7] = {'A', 'B', 'C', 'D', 'E', 'F'}; int M = 2*2*2*2*2*2-1; for(M;M>0;M--){ int A, B, C, D, E, F; A = M/(2*2*2*2*2); B = (M/(2*2*2*2))%2; C = (M/(2*2*2))%2; D = (M/(2*2))%2; E = M/2%2; F = M%2; if(A+B!=0){ if(A+D<2){ if(A+E+F==2){ if(B+C!=1){ if(C+D==1){ if(!(D==0&&E==1)){ int value[7] = {A, B, C, D, E, F}; for(int i=0;i<6;i++){ if(value[i]==1){ printf("%c,", member[i]); } } putchar('\n'); } } } } } } }
#include<stdio.h> int main(void){ char member[7] = {'A', 'B', 'C', 'D', 'E', 'F'}; int M = 2*2*2*2*2*2-1; for(M;M>0;M--){ int A, B, C, D, E, F; A = M/(2*2*2*2*2); B = (M/(2*2*2*2))%2; C = (M/(2*2*2))%2; D = (M/(2*2))%2; E = M/2%2; F = M%2; if(A+B!=0){ if(A+D<2){ if(A+E+F==2){ if(B+C!=1){ if(C+D==1){ if(!(D==0&&E==1)){ int value[7] = {A, B, C, D, E, F}; for(int i=0;i<6;i++){ if(value[i]==1){ printf("%c,", member[i]); } } putchar('\n'); } } } } } } } return 0; }
梦魔 2021-11-04 17:07:35 |
把它当成一个六位二进制数
#include<stdio.h> int main(void){ int a,b,c,d,e,f; for(a=0;a<=1;a++){ for(b=0;b<=1;b++){ for(c=0;c<=1;c++){ for(d=0;d<=1;d++){ for(e=0;e<=1;e++){ for(f=0;f<=1;f++){ if(a+b>=1 && a+d<=1 && a+e+f==2 && b-c==0 && c+d==1 && d-e>=0) printf("A=%d,B=%d,C=%d,D=%d,E=%d,F=%d\n",a,b,c,d,e,f); } } } } } } return 0; }
int main(){ int A,B,C,D,E,F; int arr[6]={0,0,0,0,0,0}; int i=0,j; for(A=0;A<2;A++){ for(B=0;B<2;B++){ for(C=0;C<2;C++){ for(D=0;D<2;D++){ for(E=0;E<2;E++){ for(F=0;F<2;F++){ if((A+B>0)&&(A+D<2)&&(A+E+F==2)&&(B+C==0||B+C==2)&&(C+D==1)&&(D+E==0||D+E==2)){ if(A==1){ arr[0]=1; } if(B==1){ arr[1]=2; } if(C==1){ arr[2]=3; } if(D==1){ arr[3]=4;
C语言训练-计算t=1+1/2+1/3+...+1/n (C语言代码)浏览:942 |
C语言程序设计教程(第三版)课后习题8.8 (C语言代码)浏览:895 |
C语言程序设计教程(第三版)课后习题6.2 (C语言代码)浏览:716 |
1009题解浏览:802 |
关于C语言变量位置的问题浏览:294 |
C语言程序设计教程(第三版)课后习题10.2 (C语言代码)浏览:755 |
分糖果 (C语言代码)浏览:980 |
C语言程序设计教程(第三版)课后习题12.6 (C语言代码)浏览:732 |
C语言程序设计教程(第三版)课后习题5.8 (C语言代码)浏览:692 |
平方数问题,oj一直是wrong answer浏览:755 |