一道关于“蚂蚁上树”的java编程题

wingardium 2010-03-26 06:20:51
有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过一只蚂蚁。
开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。
假设各位置的蚂蚁们(从3厘米依次到23厘米)每秒钟分别可以走2厘米、1厘米、3厘米、2厘米、1厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
...全文
534 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
keeya0416 2010-03-29
  • 打赏
  • 举报
回复
只求出最快是 7 秒
最慢求不出来了
wingardium 2010-03-29
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 xlnheapy 的回复:]
lz 在没????
“当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。”当头尾相撞的时候变不变方向????
[/Quote]

不好意思,忘记说明,当头尾相撞的时候前面的蚂蚁方向不变,后面追上来的那只掉头。

[Quote=引用 16 楼 tan870426 的回复:]
穷举了一下...
没找到技巧
[/Quote]

我也没找到巧妙算法,找出所有方向组合,然后求出每种组合的时间。。。。。。等待高手
xf_hhk 2010-03-28
  • 打赏
  • 举报
回复
不懂啊!!晕
feng_jyie 2010-03-27
  • 打赏
  • 举报
回复
在哪里曾经看到过
jimmy112358 2010-03-27
  • 打赏
  • 举报
回复
开始时蚂蚁的行动方向不确定,有点头晕哪
_JeffreyWu 2010-03-27
  • 打赏
  • 举报
回复
可以用灵魂算法求解最大时间,记得以前在哪里看过
灵魂算法是指当两只蚂蚁碰面后,理论上它们应该立即掉头反向而行,但此时我们可以认为它们是可以穿过对方的“灵魂”,碰面之后仍会坚持原来的方向行走,既然蚂蚁可以穿越对方而行走,那么用时最长的就是行走路线最长的那只蚂蚁了..
_JeffreyWu 2010-03-27
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <math.h>

struct Ant
{
int iPos;
float iSpeed;
};

int main()
{
int pos[] = {3,7,11,17,23};
int speed[] = {2,1,3,2,1};
Ant ant[5];
for (int i=0; i<5; i++)
{
ant[i].iPos = pos[i];
ant[i].iSpeed = speed[i];
}
int len = 27;
float min = ant[0].iPos/ant[0].iSpeed, max = 0.0;

// 以中点为分界向两边走,两只蚂蚁都不碰头
for (int i=0; i<5; i++)
{
if (ant[i].iPos < len/2)
{
float time = ant[i].iPos/ant[i].iSpeed;
if (time > min)
{
min = time;
}
}

if (ant[i].iPos > len/2)
{
float time = (len-ant[i].iPos)/ant[i].iSpeed;
if (time > min)
{
min = time;
}
}
}
printf("min: %.2f\n", min);

// 最长时间:找一只蚂蚁,使它到较远端的距离最大,速度最慢

max = ant[4].iPos/ant[4].iSpeed;
printf("max: %.2f\n", max);

return 0;
}

xlnheapy 2010-03-27
  • 打赏
  • 举报
回复
lz 在没????
“当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。”
当头尾相撞的时候变不变方向????
hepeng_8 2010-03-27
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zj821184518 的回复:]
#4所说的书应该是《编程之美》中的题4.7,其中的参数都一样,但是书中的所有蚂蚁每秒只能移动一厘米.也正因为这样lz所说的题无法用书中方法解答,而且lz的题中可能出现在前的蚂蚁被在后的蚂蚁赶上的情况,但题目中没明确说明该如何处理,那就假设速度快的蚂蚁被速度慢的挡住好了.(当然,也可能有更复杂的情况,这就要需要题目说得更清楚了)

最小时间:考虑到这样一个事实,对于每只蚂蚁,若它从左边离开木杆,……
[/Quote]
真的很难理解啊
ctlu2ct2t 2010-03-27
  • 打赏
  • 举报
回复
还是有高手呀!
whd3331933 2010-03-27
  • 打赏
  • 举报
回复
关注 学习
zings 2010-03-27
  • 打赏
  • 举报
回复
不会。。。算法没学好...
yueguangkai001 2010-03-27
  • 打赏
  • 举报
回复
感觉很多问题重复的问,我记得有个高人也贴出来过,CSDN上面搜索一下应该能够找到
_JeffreyWu 2010-03-27
  • 打赏
  • 举报
回复
求出来只有9秒,怎么感觉不对呢!
_JeffreyWu 2010-03-27
  • 打赏
  • 举报
回复
这个只能求最大时间
_JeffreyWu 2010-03-27
  • 打赏
  • 举报
回复
递归了一下,怎么觉得结果不大对呢! 一起看看

#include <iostream>
using namespace std;

#define ANT_COUNT 5 // 蚂蚁数量
#define ROAD_LENGTH 27 // 杆长度
#define WAY_AHEAD true // 前进
#define WAY_BACK false // 后退
#define GAME_OVER -100 // 出杆

class CAnt
{
public:
// 构造函数
CAnt();
// 初始化蚂蚁信息
void Init(int iPos, int iSpeed, bool bWay);

public:
int m_iPos; // 位置
int m_iSpeed; // 速度
bool m_bWay; // 方向 true:前进 false:反向
int m_iCurPos; // 蚂蚁当前位置
// bool m_bFinish; // 是否走完
static int m_iAntCount; // 当前蚂蚁数量
static int m_iTime; // 共用总时间

};

int CAnt::m_iAntCount = ANT_COUNT;
int CAnt::m_iTime = 0;

// 构造函数
CAnt::CAnt()
{
m_iPos = 0;
m_iSpeed = 0;
m_bWay = 0;
m_iCurPos = 0;
//m_bFinish = false;
}

void CAnt::Init(int iPos, int iSpeed, bool bWay)
{
m_iPos = iPos;
m_iCurPos = iPos;
m_iSpeed = iSpeed;
m_bWay = bWay;
}

void Go(CAnt *pAnt)
{
for (int i=0; i<ANT_COUNT; i++)
{
if (pAnt[i].m_iCurPos == GAME_OVER) continue;

if (pAnt[i].m_bWay == WAY_AHEAD)
{
pAnt[i].m_iCurPos += pAnt[i].m_iSpeed;
}
else
{
pAnt[i].m_iCurPos -= pAnt[i].m_iSpeed;
}
}

// 相遇
for (int i=0; i<ANT_COUNT-1; i++)
{
if (pAnt[i].m_iCurPos == GAME_OVER) continue;

for (int j=i+1; j<ANT_COUNT; j++)
{
if (pAnt[j].m_iCurPos == GAME_OVER) continue;
if (pAnt[i].m_iCurPos == pAnt[j].m_iCurPos)
{
pAnt[i].m_bWay = !pAnt[i].m_bWay;
pAnt[j].m_bWay = !pAnt[j].m_bWay;
printf("注意: %d 和 %d相遇,反向\n\n", i, j);
}
else
{
if (pAnt[i].m_iCurPos > ROAD_LENGTH || pAnt[i].m_iCurPos <= 0)
{
pAnt[i].m_iCurPos = GAME_OVER; // 完成
CAnt::m_iAntCount--;
}
}
}
}

if (pAnt[CAnt::m_iAntCount-1].m_iCurPos > ROAD_LENGTH ||
pAnt[CAnt::m_iAntCount-1].m_iCurPos <= 0 &&
CAnt::m_iAntCount>0)
{
pAnt[CAnt::m_iAntCount-1].m_iCurPos = GAME_OVER; // 完成
CAnt::m_iAntCount--;
}

if (CAnt::m_iAntCount <= 0)
{
printf("剩余: %d\n", CAnt::m_iAntCount);
printf("完成! \n\n");
return;
}
else
{
printf("第 %d 秒", ++CAnt::m_iTime);
printf(" 剩余: %d\n\n", CAnt::m_iAntCount);
}
Go(pAnt);
}


int main()
{
CAnt *pAnt = new CAnt[ANT_COUNT]();

// 初始化5只蚂蚁
int iPos[] = {3,7,11,17,23};
int iSpeed[] = {2,1,3,2,1};
for (int i=0; i<ANT_COUNT; i++)
{
pAnt[i].Init(iPos[i], iSpeed[i], WAY_AHEAD);
}

Go(pAnt);

delete [] pAnt;
return 0;
}
tan870426 2010-03-27
  • 打赏
  • 举报
回复
不过在判断相遇条件的时候有点问题...

如果两只蚂蚁直间相隔2cm,但再经过一秒肯定就已经穿过了...
这个地方不好解决!
tan870426 2010-03-27
  • 打赏
  • 举报
回复
穷举了一下...
没找到技巧

const int PRECISION = 1000;
const int MAXPLACE = 27*PRECISION;

const int ONEPLACE = 3*PRECISION;
const int TWOPLACE = 7*PRECISION;
const int THRPLACE = 11*PRECISION;
const int FOURPLACE = 17*PRECISION;
const int FIVEPLACE = 23*PRECISION;

class AntRun
{
public:
AntRun(int, int, int);
void run(int);
void converse();
void SetTime(int);
bool GetIsEnd();
void SetSpeed(int);//初始化蚂蚁开始的朝向

bool operator == (const AntRun& R)
{
//只要两者距离小于3就认为已经相遇
if ( 0>(m_iSpeed*R.m_iSpeed) )
{
return ((abs(m_iStation - R.m_iStation) < 3));
}
else
{
return (m_iStation == R.m_iStation);
}
}
private:
int m_iStation;
int m_iEndTime;
int m_iSpeed;
bool m_isEnd;
int m_iNum;
};

AntRun::AntRun(int iStation ,int iSpeed, int iNum)
{
m_iStation = iStation;
m_iSpeed = iSpeed;
m_iNum = iNum;
m_isEnd = false;
}

void AntRun::run(int iTime)
{
if ( (m_iStation>0) && (m_iStation<MAXPLACE) && !m_isEnd )
{
m_iStation += m_iSpeed;
}

if (((m_iStation<=0) || (m_iStation>=MAXPLACE)) && !m_isEnd)
{
SetTime(iTime);
m_isEnd = true;

cout << m_iNum << " time:" << (float)m_iEndTime/PRECISION << "; " ;
}
}

void AntRun::converse()
{
m_iSpeed = -m_iSpeed;
}

void AntRun::SetTime(int iTime)
{
m_iEndTime = iTime;
}

bool AntRun::GetIsEnd()
{
return m_isEnd;
}

void AntRun::SetSpeed(int a)
{
if (0 != a)
{
m_iSpeed = -m_iSpeed;
}
}
void main()
{
for (int i=0; i<32; i++)
{
AntRun AntOne(ONEPLACE, 2, 1);
AntRun AntTwo(TWOPLACE, 1, 2);
AntRun AntThr(THRPLACE, 3, 3);
AntRun AntFour(FOURPLACE, 2, 4);
AntRun AntFive(FIVEPLACE, 1, 5);

//按位与设定朝向
AntOne.SetSpeed(i&1);
AntTwo.SetSpeed(i&2);
AntThr.SetSpeed(i&4);
AntFour.SetSpeed(i&8);
AntFive.SetSpeed(i&16);

int iTime = 0;
while (1)
{
AntOne.run(iTime);
AntTwo.run(iTime);
AntThr.run(iTime);
AntFour.run(iTime);
AntFive.run(iTime);

if (AntOne == AntTwo)
{
AntOne.converse();
AntTwo.converse();
}
else if (AntTwo == AntThr)
{
AntTwo.converse();
AntThr.converse();
}
else if (AntThr == AntFour)
{
AntThr.converse();
AntFour.converse();
}
else if (AntFour == AntFive)
{
AntFour.converse();
AntFive.converse();
}

if ( AntOne.GetIsEnd()
&& AntTwo.GetIsEnd()
&& AntThr.GetIsEnd()
&& AntFour.GetIsEnd()
&& AntFive.GetIsEnd() )
{
break;
}
iTime++;
}
cout << endl;
}
system("color 0e");
}

qq327989741 2010-03-27
  • 打赏
  • 举报
回复
貌似有难度 等待高手中
bawgiitx 2010-03-26
  • 打赏
  • 举报
回复
看滴晕呼呼滴
加载更多回复(7)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧