编程之美:第四章 数字之趣 4.7蚂蚁爬杆

/*
蚂蚁爬杆:
有一个27厘米的细木杆,在第3厘米,7厘米,11厘米,17厘米,23厘米这五个位置各有一只蚂蚁,木杆很细,不能同时通过通过两只蚂蚁。开始时,蚂蚁的头朝左还是
朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,它们会同时调头朝相反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,
求所有蚂蚁离开木杆的最短时间和最长时间。

解法2:
每一个复杂问题的背后,都有一些简单的规律,无论是在面试中还是在实际工作中都是这样。化繁为简。问题时求时间,不需要求具体怎么运动。
碰头的过程可以分为:
碰头前,碰头,碰头后。虽然两个蚂蚁相遇后一掉头往反向走,但是可以看做蚂蚁相遇后,擦肩而过,是否碰头不是重要的。这样每个蚂蚁运动的诡异不一样,
但是蚂蚁离开木杆的时间不变,只需要分别计算出每个蚂蚁离开木杆的时间,就可以求出所有蚂蚁离开木杆的时间。
这样程序只需要遍历所有蚂蚁,把每个蚂蚁走出木杆的最长时间(蚂蚁离自己较远的一端走去),最短时间(离自己较近的一端走去),之后,分别得到最大值,
即为所求:

扩展问题:
1第i个蚂蚁吗,什么时候走出杆
2

输入:
5(位置总数) 27(木杆长度)
3 7 11 17 23(每个位置的距离)
输出:
11(所有蚂蚁离开木杆的最短时间) 24(所有蚂蚁离开木杆的最长时间)
*/

/*
关键:
1 虽然两个蚂蚁相遇后一掉头往反向走,但是可以看做蚂蚁相遇后,擦肩而过,是否碰头不是重要的。这样每个蚂蚁运动的诡异不一样,
但是蚂蚁离开木杆的时间不变,只需要分别计算出每个蚂蚁离开木杆的时间,就可以求出所有蚂蚁离开木杆的时间。
2 int iMin = (iPoleLen - pArr[0],pArr[0] );
3 程序还可以优化为,分别计算离中点最近的一点和离任一末端最近的一点,再计算时间
*/

#include <stdio.h>
#include <algorithm>
#include <iostream>

using namespace std;

const int MAXSIZE = 10000;

int min(int a,int b)
{
	return a < b ?  a : b;
}


pair<int,int> antMinMaxLeaveTime(int* pArr,int iLen,int iPoleLen)
{
	int iMin = (iPoleLen - pArr[0],pArr[0] );
	int iMax = iPoleLen - iMin;
	int iTempMin,iTempMax;
	for(int i = 1 ; i < iLen ;i++)
	{
		iTempMin = min(iPoleLen - pArr[i],pArr[i]);
		iTempMax = iPoleLen - iTempMin;
		if(iTempMin > iMin)
		{
			iMin = iTempMin;
		}
		if(iTempMax > iMax)
		{
			iMax = iTempMax;
		}
	}
	return make_pair<int,int>(iMin,iMax);
}

void process()
{
	int iTotalPosition,iPoleLen;
	int iArr[MAXSIZE];
	while(EOF != scanf("%d %d",&iTotalPosition,&iPoleLen))
	{
		if(iTotalPosition <= 0 || iPoleLen <= 0)
		{
			continue;
		}
		for(int i = 0 ; i < iTotalPosition ; i++)
		{
			scanf("%d",&iArr[i]);
		}
		pair<int,int> pairRet = antMinMaxLeaveTime(iArr,iTotalPosition,iPoleLen);
		printf("%d %d\n",pairRet.first,pairRet.second);
	}
}

int main(int argc,char* argv[])
{
	process();
	getchar();
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值