加油鸭赛跑问题

c语言 思考题:

使用只提供6只加油鸭的比赛场地,从26只加油鸭中选出3只跑出最快的,求出最快的方法(比赛次数最少)。

/********/
//Editor:kyle
/********/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define S1 100 //第一名是第五组的 
#define S2 10 //第二名是第五组的 
#define S3 110//第一第二名都是第五组的 

//struct bull{
//	char goup;
//	int speed;
//};


int match(int*arg); //冒泡排序法,得到比赛结果 
//int arrg(int* arg[]);



int main()
{
//26头牛,每头牛有自己的速度 ,分5组 
//	static int goup[6]={34,76,22,66,99,1,98,12,54,34,45,76,97,21,29,31,55,58,50,40,70,71,88,80,5,91};
//还是直接分组比较好处理 
	int goup1[6] = {26,25,24,23,22,21};
	int goup2[6] = {20,19,18,17,16,15};
	int goup3[6] = {14,13,12,11,10,9};
	int goup4[6] = {8,7,6,5,4,3};
	int goup5[6] = {99,97};//这种偶然情况,比赛次数需要5次; 
	//int goup5[6] = {2,1}; 若是此情况,则比赛次数是6次 
	
	int round1[6]={0};
	int round2[6]={0};
	int i=0;
	
	int* p1 = NULL;
	int* p2 = NULL;
	int* p3 = NULL;
	int flag = 0;//标记不同的情况 

	int result[3] = {0};//来存比赛最终结果 
	int cnt = 0;//用来记录比赛次数 
	
	//把前四组满员的牛拿去比赛,重排他们的速度顺序 
	cnt = match(goup1);//第一次比赛 
	cnt = match(goup2);//第二次比赛 
	cnt = match(goup3);//第三次比赛 
	match(goup4);//第四次比赛 
	//把每组的第一名以及未参与过比赛的第五组的两头牛凑成一组 
	round1[0] = goup1[0];
	round1[1] = goup2[0];
	round1[2] = goup3[0];
	round1[3] = goup4[0];
	round1[4] = goup5[0];
	round1[5] = goup5[1];
	//将新的一组进行比赛,此次比赛可以知到所有牛,跑最快的 
	cnt = match(round1); //第五次比赛 
	result[0] = round1[0];
	printf("第五次比赛结束,这次比赛的情况如下:\n");

/********************find out where the most fast bull come from****************/
{
	if(round1[0] == goup1[0])
	{
		p1=&goup1;printf("最快的牛来自goup1\n");	
	} 
	if(round1[0] == goup2[0])
	{
		p1=&goup2;printf("最快的牛来自goup2\n");	
	}
	if(round1[0] == goup3[0])
	{
		p1=&goup3;printf("最快的牛来自goup3\n");	
	} 
	if(round1[0] == goup4[0])
	{
		p1=&goup4;printf("最快的牛来自goup4\n");	
	 } 
	//第五组的情况要另外讨论
	if(round1[0] == goup5[0])
	{
		p1=&goup5[0];printf("最快的牛来自goup5[0]\n");
		flag += 100;
	 } 
	if(round1[0] == goup5[1])
	{
		p1=&goup5[1];printf("最快的牛来自goup5[1]\n");
		flag +=100;
	 } 
	
	printf("它的速度是:%d\n",round1[0]);
}
/*********************************************************/

/*****************find out where the second faster bull come from ***************/
{
	if(round1[1] == goup1[0])
	{
		p2=&goup1;printf("最2快的牛来自goup1\n");	
	} 
	if(round1[1] == goup2[0])
	{
		p2=&goup2;printf("最2快的牛来自goup2\n");	
	}
	if(round1[1] == goup3[0])
	{
		p2=&goup3;printf("最2快的牛来自goup3\n");	
	} 
	if(round1[1] == goup4[0])
	{
		p2=&goup4;printf("最2快的牛来自goup4\n");	
	 } 
	//第五组的情况要另外讨论
	if(round1[1] == goup5[0])
	{
		p2=&goup5[0];printf("最2快的牛来自goup5[0]\n");
		flag += 10;
	 } 
	if(round1[1] == goup5[1])
	{
		p2=&goup5[1];printf("最2快的牛来自goup5[1]\n");
		flag += 10;
	 } 
	
	printf("它的速度是:%d\n",round1[1]);
}
	/************************************************/
	
/*****************find out where the third faster bull come from ***************/
{
	if(round1[2] == goup1[0])
	{
		p3=&goup1;printf("最3快的牛来自goup1\n");	
	} 
	if(round1[2] == goup2[0])
	{
		p3=&goup2;printf("最3快的牛来自goup2\n");	
	}
	if(round1[2] == goup3[0])
	{
		p3=&goup3;printf("最3快的牛来自goup3\n");	
	} 
	if(round1[2] == goup4[0])
	{
		p3=&goup4;printf("最3快的牛来自goup4\n");	
	 } 
	//第五组的情况要另外讨论
	if(round1[2] == goup5[0])
	{
		p3=&goup5[0];printf("最3快的牛来自goup5[0]\n");
		//flag += 1;
	 } 
	if(round1[2] == goup5[1])
	{
		p3=&goup5[1];printf("最3快的牛来自goup5[1]\n");
		//flag += 1;
	 } 
	
	printf("它的速度是:%d\n",round1[2]);
}
/************************************************/

/*******************第六场比赛(运气好的话,第六场不需要举办)********************/	
	if(0 == flag)//第一名的同组的老二老三要拿出来和其他人比,同理第二名同组的老二也要出来比赛 
	{
		round2[0] = *(p1+1);
		round2[1] = *(p1+2);
		round2[2] = *(p2);
		round2[3] = *(p2+1);
		round2[4] = round1[2];
		cnt = match(round2);
	//	printf("round2[0] = %d,round2[1] = %d\n",round2[0],round2[1]);
		result[1] = round2[0];
		result[2] = round2[1];
	}
	
	//以下一部分处理第五组跑得比较快的情况,也不是很复杂,就是排序要思考一下 
	if(flag>0)
	{
		if(flag == S1) //如果第一名是第五组的,那么第五场比赛第二名的牛就是全员牛的第二名 
		{
			round2[0] = *(p2+1);//把第二名同组的第二名的牛拿出来和第五场比赛第三名的来较量 
			round2[1] = round1[2];
			cnt = match(round2);
		//	printf("round2[0] = %d\n",round2[0]);
			result[1] = round1[1];
			result[2] = round2[0];
		}
		if(flag == S2)//第一名同组的第二第三名拿出来和本场比赛第二第三名比赛 
		{
			round2[0] = *(p1+1); 
			round2[1] = *(p1+2);
			round2[2] = *(p2);
			round2[3] = round1[2];
			cnt = match(round2);
		//	printf("round2[0] = %d,round2[1] = %d\n",round2[0],round2[1]);
			result[1] = round2[0];
			result[2] = round2[1];
		}
		if(flag == S3)//比赛结果直接出来了,运气比较好的情况下,不需要比赛第六场比赛 
		{
			result[1] = round1[1];
			result[2] = round1[2];
		}
	}
/****************************************************************/
	system("cls");
	printf("最后的结果已经出来,最快的三头牛分别速度是:%d,%d,%d\n",result[0],result[1],result[2]); 
	printf("比赛共进行了 %d 次\n",cnt);
	return 0;
}


int match(int* arg)
{
	static int cnt=0;
	
	int i=0;
	int j=0;
	int big=0;
	for(j=0;j<6;j++)
	{
		for(i=j;i<6;i++)
		{
			if(*(arg+j)<*(arg+i))
			{
				big = *(arg+i);
				*(arg+i) = *(arg+j);
				*(arg+j) = big;

			}
		}
	}
	cnt++;
	printf("第 %d 轮比赛已结束。\n",cnt);
	return cnt;
}

上面的看得有点晕,可以看以下这段,比较简明一些,几乎一样的思路。

/**********************
Created:	Aug 31
Modified:	Sep 05 
Editor:		Kyle

Description:
	使用只提供6只牛的比赛场地,从26只牛中选出3只跑出最快的,求出最快的方法。
	经过验证,此方法总可以将26只牛中速度最快的3只找出来,即使速度有相同的时候。 
***********************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int m_cnt = 0;  				 //比赛进行的次数

int match(int*arg); 			//冒泡排序法,得到比赛结果 
void showBull(int const *arg); 	//显示数组,看当前组牛的速度 

int main()
{
	/*26头牛,每头牛有自己的速度 ,分5组*/
	/*可随意更改分组内牛的速度*/ 
	int goup1[6] = {27,26,25,23,22,21};
	int goup2[6] = {20,19,18,17,16,15};
	int goup3[6] = {14,13,12,11,10,9};
	int goup4[6] = {8,7,6,5,4,3};
	int goup5[6] = {27,1};

	
	int round1[6]={0};	//存储参加第五场比赛的牛
	int round2[6]={0};	//存储参加第六场比赛的牛
	
	int* p1 = NULL; 	//第五场比赛第一名所在组指针
	int* p2 = NULL;		//第五场比赛第二名所在组指针

	int result[3] = {0};//来存比赛最终结果,最快三头牛的成绩
	
	printf("当前所有牛的速度:\n");
	showBull(goup1);
	showBull(goup2);
	showBull(goup3);
	showBull(goup4);
	showBull(goup5);
	
	//把前四组满员的牛拿去比赛,重排他们的速度顺序 
	match(goup1);		//第一次比赛 
	match(goup2);		//第二次比赛 
	match(goup3);		//第三次比赛 
	match(goup4);		//第四次比赛 
	
	//把每组的第一名以及未参与过比赛的第五组的两头牛凑成一组 
	round1[0] = goup1[0];
	round1[1] = goup2[0];
	round1[2] = goup3[0];
	round1[3] = goup4[0];
	round1[4] = goup5[0];
	round1[5] = goup5[1];

	//将新的一组进行比赛,此次比赛可以知到所有牛,跑最快的 
	match(round1); 		//第五次比赛
/********************找到第一名的牛来自第几组****************/

	if(round1[0] == goup1[0])
	{
		p1=&goup1;
		goup1[0] = 0;	//清零为了避免第一名与第二名同速冲突,下同 
	} 
	else if(round1[0] == goup2[0]) 
	{
		p1=&goup2;	
		goup2[0] = 0;
	}
	else if(round1[0] == goup3[0])
	{
		p1=&goup3;
		goup3[0] = 0;
	} 
	else if(round1[0] == goup4[0])
	{
		p1=&goup4;
		goup4[0] = 0;
	}  
	else if(round1[0] == goup5[0])
	{
		p1=&goup5;
		goup5[0] = 0;
	} 
	else if(round1[0] == goup5[1])
	{
		p1=&goup5;
		goup5[1] = 0;
	} 

/*****************找到第二名的牛来自第几组****************/
	if(round1[1] == goup1[0])
	{
		p2=&goup1;	
	} 
	if(round1[1] == goup2[0])
	{
		p2=&goup2;	
	}
	if(round1[1] == goup3[0])
	{
		p2=&goup3;
	} 
	if(round1[1] == goup4[0])
	{
		p2=&goup4;	
	} 
	if((round1[1] == goup5[0]) || (round1[1] == goup5[1]))
	{
		p2=&goup5;	
	} 
	
	/******************通过推理,将所有可能获得前三名的牛组合在同一组里****************************/
	round2[0] = *(p1+1);	//与第一名的牛同组的第二第三名,可能比其他组的牛都快,有机会成为总决赛第二名及第三名
	round2[1] = *(p1+2);
	*(p1+1) = 0; 			//第一名和第二名同在第五组的时候,避免重取发生错误 
	round2[2] = *(p2);		//第二名的牛以及与第二名同组第二名的牛,有机会分别竞争总决赛第二名及第三名
	round2[3] = *(p2+1);
	round2[4] = round1[2];	//第三名的牛仅有机会竞争总决赛第三名
	round2[5] = round1[0];  //第一名的牛将毫无疑问会继续成为总决赛第一名
	
	printf("\n***根据前5场比赛结果推理,将所有可能获得前三名的牛组合在一组进行总决赛***\n");
	match(round2);			//将所有可能获得前三名的牛组合进行比赛 
	
	result[0] = round1[0];	//冠军牛
	result[1] = round2[1];  //亚军牛
	result[2] = round2[2];	//季军牛

	printf("\n最快的三头牛分别速度是:%d,%d,%d\n",result[0],result[1],result[2]); 
	printf("比赛共进行了 %d 次。\n",m_cnt);
	return 0;
}

int match(int* arg)
{
	int i=0;
	int j=0;
	int big=0;
	m_cnt++;
	printf("\n*****第 %d 轮比赛开始*****\n",m_cnt);
	printf("参与比赛的牛速度分别是:\n");
	for(i=0;i<6;i++)
	{
		printf("%d ",*(arg+i));
	}
	for(j=0;j<6;j++)
	{
		for(i=j;i<6;i++)
		{
			if(*(arg+j)<*(arg+i))
			{
				big = *(arg+i);
				*(arg+i) = *(arg+j);
				*(arg+j) = big;
			}
		}
	}
	printf("\n比赛结果是:\n");
	for(i=0;i<6;i++)
	{
		printf("%d ",*(arg+i));
	}
	
	printf("\n第 %d 轮比赛已结束。\n",m_cnt);
	return m_cnt;
}

void showBull(int const *arg)
{
	int i=0;
	for(i=0;i<6;i++)
	{
		if(*(arg+i) == 0)
		{
			continue; 
		} 
		printf("%4d ",*(arg+i));
	}
	printf("\n");
 } 

 

结果:需要6场比赛,运气好的话5场就可以。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值