Manchester


私信TA

用户名:wenyajie

访问量:332128

签 名:

在历史前进的逻辑中前进,这个逻辑就是人心向背的逻辑

等  级
排  名 1
经  验 65567
参赛次数 1
文章发表 188
年  龄 0
在职情况 学生
学  校 Xiamen University
专  业 计算机科学

  自我简介:

在历史前进的逻辑中前进,这个逻辑就是人心向背的逻辑

解题思路:

(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);可自行验证;

得到如图:

2017-12-11 00-04-10屏幕截图.png

2017-12-11 00-05-30屏幕截图.png

中间的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 人评分

  评论区

强啊大佬
2022-02-16 19:13:31
把它当成一个六位二进制数
#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');
							}
						}
					}
				}
			}
		}
	}
2021-11-05 08:50: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');
							}
						}
					}
				}
			}
		}
	}
	return 0;
}
2021-11-04 17:05:42
#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;
}
2021-07-26 21:16:36
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;
2021-06-24 17:02:13
牛皮牛皮! 加油
2021-04-09 20:29:34
比起题解,这思维才是精华
厉害!
2020-03-14 17:57:32
深受启发,厉害了!
2020-03-04 20:03:20