穷举算法思路

忘记排名?算法伺候

问题:
在一次竞赛中,A、B、C、D、E 等五人经过激烈的角逐,
最终取得了各自的名 次,他们的一个好朋友很遗憾没有观看到比赛,
在比赛结束后这个朋友询问他们 之间的名次是得知:
C 不是第一名,D 比 E 低二个名次,而 E 不是第二名,
A 即不是第一名,也不是最后一名,B 比 C 低一个名次。
编写程序,计算这五个人各自的名次并输出

提示:D比E低二个名次,那D和E的位置肯定是在(1,3)、(2,4)、(3,5)而E不是第二名,后面还有其他条件的限制。

人脑算的话,假设A,B,C,D,E,这排名就是这样排的,拿纸笔或者电脑画图几分钟就套出来,但我们是让计算机算。

穷举算法伺候
脑算的话
这是一组组合
A B C D E
A B C E D
A B D E C
A B D C E
A B E C D
A B E D C
加上这一组合后面的C、D、E这样的话6×4=24 24×5=120,A是第一的可能就有24种,总共有120种组合。
假设A,B,C,D,E,A是第一名,A的全部可能遍历完之后,在把B当做第一名,后面一次类推,A,B,C,D,E,定义一组字符数组,然后再弄个for循环往里面套,一组组合传进字符数组后,最后再加个条件,条件就是问题,一组组合传进去,就判断条件,不是就下一次组,直到全部遍历完。
在这里插入图片描述
代码实现:

#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#include<Windows.h>


int logic_reasoning(char str1_tmp[5]){
//返回值说明:0代表假1代表真

	//判断一. C不是第一名
	if(str1_tmp[0]=='C')return 0;

	//判断二. D比E低二个名次
	int flag =0;//标记 
	for(int k=0;k<3;k++){
		if(str1_tmp[k]=='E' && str1_tmp[k+2]=='D'){
			flag = 1;
		}
		else continue;
	}
	if(flag==0) return 0;//假 调回返回0

	//判断三. E不是第二名
	if(str1_tmp[1]=='E') return 0;

	//判断四.A即不是第一名,也不是最后一名
	if(str1_tmp[0]=='A'||str1_tmp[4]=='A') return 0;

	//判断五.B 比 C 低一个名次
	flag=0;//初始化标记
	for(int k=0;k<4;k++){
		if(str1_tmp[k]=='C'&&str1_tmp[k+1]=='B'){
			flag=1;
		}
		else continue;
	}
	if(flag==0) return 0;
	return 1;//推理完成返回真 1
}
int main(void){

	char str1[5]={'A','B','C','D','E'};
	char tmp[5];//存放计算后的五人名次

	memset(tmp, '\0', sizeof(char) * 5);//清空内存

	//A i0=0;
	for(int i0=0;i0<5;i0++){
		tmp[0]=str1[i0];

		//B i1=1;
		for(int i1=0;i1<5;i1++){
			if(i1==i0){continue;}
			tmp[1]=str1[i1];

			//C i2=2;
			for(int i2=0;i2<5;i2++){
				if(i2==i0||i2==i1){continue;}
				tmp[2]=str1[i2];

				//D i3=3;
				for(int i3=0;i3<5;i3++){
					if(i3==i0||i3==i1||i3==i2){continue;}
					tmp[3]=str1[i3];

					//E i4=4;
					for(int i4=0;i4<5;i4++){
						if(i4==i0||i4==i1||i4==i2||i4==i3){continue;}
						tmp[4]=str1[i4];
						if(logic_reasoning(tmp)){
							printf("已完成您的结果:\n");
							for(int i=0;i<5;i++){
								printf(" %c ",tmp[i]);
							}
							printf("\n");
						}
					}
				}
			}
		}
	}

	system("pause");
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值