最快过桥思维题

前言:

1.博主实力有限,有什么错误地方,请你斧正!谢谢!
2.思维题真的真的让人头大 ,但却有意思。0.0.

题目:

有N(N>=2)个人过桥,只有一把手电筒。每个人过桥速度(分钟)由键盘输入。如过2人过桥,时间为速度最慢的那个。问N个人过完桥需要的最短时间。

思路:

1.时间最短,必然传递手电筒的时间最短。因此需要将速度最快的2人做为传手电筒的人选。
# 前言:
1.博主实力有限,有什么错误地方,请你斧正!谢谢!
2.思维题真的真的让人头大

见题目:

有N(N>=2)个人过桥,只有一把手电筒。每个人过桥速度(分钟)由键盘输入。如过2人过桥,时间为速度最慢的那个。问N个人过完桥需要的最短时间。

思路:

1.时间最短,必然传递手电筒的时间最短。因此需要将速度最快的2人做为传手电筒的人选。
2…考虑到手电筒的要求,我们必须让速度的在速度的之前到达对岸。这样不仅桥上时间可以减断,而且当速度慢的到了后,可以让速度快的传送手电筒。
3.实际情况;速度最快次快的2人先走,回来一个速度最快的。然后速度最慢2人过去,速度次快的人回来.然后循环。这样在速度最快次快的2人的配合下,极大的减短,不用考虑中间速度的使用。
4.每次循环相当于送过去2人
5.最后剩3人,和2人的特殊情况,要区分。

程序

从小到大排序数组:
void order_board(int *p,int n)//选择法排序,从小到大。
{
	int i = 0;
	int j = 0;
	int min = 0;
	for (i = 0; i < n - 1; i++)
	{
	
		min = i;
		for (j = i + 1; j < n; j++)
		{
			if (p[j] < p[min])min = j;//遍历找到数组最小的下标。
		}
	
		if (min != i)//选出的下标不为i就交换
		{
		
			int tmp = p[i];
			p[i] = p[min];
			p[min] = tmp;
		}
	}
}
选择出最慢的2个人
int max_peo(int* p, int n)//选择出最长的时间。并在数组中将其重值为0.
{
	int i = 0;
	int max = 0;
	for (i = 0; i < n; i++)
	{
		if (p[i] > p[max])max = i;

	}

	int tmp = p[max];
	p[max] = 0;
	return tmp;
}
循环的开始
void fun(int* p, int n)
{
	int tmp = n;//每次循环相当于送过去2人.
			int max_max = 0;//用于选出的最慢的人
			int max_min = 0;//用于选出的次慢的人.
			int max1 = p[0];//速度最快的人
			int max2 = p[1];//速度次快的人
			int Time = 0;
			while (1)
			{
				max_max = max_peo(p,n); //选出的最慢的人
				max_min = max_peo(p, n); //选出的次慢的人
				if (tmp>3)
				{
					Time = Time + max2 + max1 + max_max + max2;
						tmp-=2;
				}
				else if (tmp==3)//最后只剩3人的特殊情况
				{
					Time =Time+ max1 + max_max + max_min;
					break;
				}
				else if (tmp == 2)//最后只剩2人的特殊情况
				{
				
					Time = Time + max2;
					break;
				}
			}

			printf("所需时间为:%d\n", Time);
}

全部程序(以多组输入定义main函数)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> 

void order_board(int *p,int n)//选择法排序,从小到大。
{
	int i = 0;
	int j = 0;
	int min = 0;
	for (i = 0; i < n - 1; i++)
	{
	
		min = i;
		for (j = i + 1; j < n; j++)
		{
			if (p[j] < p[min])min = j;//遍历找到数组最小的下标。
		}
	
		if (min != i)//选出的下标不为i就交换
		{
		
			int tmp = p[i];
			p[i] = p[min];
			p[min] = tmp;
		}
	}
}

int max_peo(int* p, int n)//选择出最长的时间。并在数组中将其重值为0.
{
	int i = 0;
	int max = 0;
	for (i = 0; i < n; i++)
	{
		if (p[i] > p[max])max = i;

	}

	int tmp = p[max];
	p[max] = 0;
	return tmp;
}
void fun(int* p, int n)
{
	int tmp = n;
			int max_max = 0;//用于选出的最慢的人
			int max_min = 0;//用于选出的次慢的人.
			int max1 = p[0];//速度最快的人
			int max2 = p[1];//速度次快的人
			int Time = 0;//每次循环相当于送过去2人.
			while (1)
			{
				max_max = max_peo(p,n); //选出的最慢的人
				max_min = max_peo(p, n); //选出的次慢的人
				if (tmp>3)
				{
					Time = Time + max2 + max1 + max_max + max2;
						tmp-=2;
				}
				else if (tmp==3)//最后只剩3人的特殊情况
				{
					Time =Time+ max1 + max_max + max_min;
					break;
				}
				else if (tmp == 2)//最后只剩2人的特殊情况
				{
				
					Time = Time + max2;
					break;
				}
			}

			printf("所需时间为:%d\n", Time);
}

int main ()
{
	int  peo[100] = { 0};
	int i = 0;
	while (~scanf("%d", &peo[i++]))
	{
		if(getchar() == '\n')
		{
			int sz = i;
			order_board(peo, sz);
			fun(peo, sz);
			i = 0;//每次都可以重新赋值数组。
		}
	}
	return 0;
}

效果图

image-20210816173410527

image-20210816203928965

  • 22
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值