百度试题讲解:蚂蚁们和木杆

本文探讨了一个有趣的问题:在一根27厘米长的木杆上,分别在特定位置放置五只蚂蚁,蚂蚁只能向前走或调头,相遇时会改变方向。通过编程计算所有蚂蚁离开木杆所需的最小和最大时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* 有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。 * 木杆很细,不能同时通过一只蚂蚁。开始 时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头, * 但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。 * 编写程序,求所有蚂蚁都离开木杆 的最小时间和最大时间。 思路: 最小时间很好算,不过顾于最大时间还是要将所有蚂蚁可能的初始方向考虑在内,单独计算最小时间也没有太大优化。 所以,这里的解决思路是将所有初始情况列出(这个需要点技巧,下面我会指出),然后再让蚂蚁前进,直到结束。然后就可以得出所要求的最大最小时间。 边看代码边讲吧~~ 欢迎讨论 /* * FileName: AntMarch.cpp * Type: C++ * Copyright: (c) 2009 Jingyi Xiao * Authors: Jingyi Xiao * Description: */ #include iostream using namespace std; #define STEP 1 // 这里是蚂蚁每秒行驶距离 #define MAX_ANTS 5 // 这里是蚂蚁个数 #define LENGTH 27 // 杆长度 const int posible_directions[2] = {-1, 1}; // 可能的方向 const int init_pos[MAX_ANTS] = {3, 7, 11, 17, 23}; // 初始位置 int march_end = 0; // 蚂蚁行驶结束标志 int max_time = 0, min_time = LENGTH; // 这个就是最后要求的了 int MarchNow (int ant_id, int directions[], int pos[]){ // 这个函数就是蚂蚁行驶的控制函数了 if (pos[ant_id] <= 0 || pos[ant_id] >= LENGTH){ // 到头了~~ return 0; } if (pos[ant_id] == pos[ant_id-1] && pos[ant_id] == pos[ant_id+1]){ // Aha, no way to go, just change direction directions[ant_id + directions[ant_id]] *= -1; // 注意这里,方向控制哦,看清楚谁掉头~~ directions[ant_id] *= -1; } else{ // first march pos[ant_id] += directions[ant_id] * STEP; // 前进~~~ if (pos[ant_id] <= 0 || pos[ant_id] >= LENGTH) { // 到头啦,不走了,累了~~ ++march_end; return 0; } // check if meet others, must be in the current direction if (pos[ant_id] == pos[ant_id + directions[ant_id]] // 这里很重要哦~ && directions[ant_id] != directions[ant_id + directions[ant_id]]){ directions[ant_id + directions[ant_id]] *= -1; directions[ant_id] *= -1; } } return 1; } int GiveDirection(int directions[], int n, int i){ // 这个函数是老大,给出所有初始数据!! if (i == n) { int tmp_directions[MAX_ANTS]; int tmp_pos[MAX_ANTS]; int count_time = 0; // Copy the data to tmp for (int j = 0; j < n; ++j) tmp_directions[j] = directions[j]; for (int j = 0; j < n; ++j) tmp_pos[j] = init_pos[j]; // The direction have been gave, Now ants marching : -) while (1){ // 这里我注释很明白,不翻译了哈~~ if (march_end > 4) break; // All march have been ended for (int j = 0; j < MAX_ANTS; ++j){ // every j means a ant id MarchNow(j, tmp_directions, tmp_pos); } ++count_time; } // now give the current report max_time = (count_time > max_time ? count_time : max_time); min_time = (count_time < min_time ? count_time : min_time); march_end = 0; } else // 这里就是我苦思冥想的技巧了(递归妙用),嘿嘿~ for (int index = 0; index < 2; ++index){ directions[i] = posible_directions[index]; GiveDirection(directions, n, i+1); } } int AntMarch (){ // 这个不用说,老大的老大!!~~ int directions[MAX_ANTS]; GiveDirection(directions, MAX_ANTS, 0); // ok it's time to output cout << "max time: " << max_time << endl << "min_time: " << min_time << endl; return 0; } 当然,在给出所有初始数据的实现里,由于题目只给出了两个方向,所以可以用二进制来给出哦,嘿嘿,这个能省不少时间空间呢!具体实现我不说了,有兴趣,你可以自己试试,有问题就和我探讨了~~ 当然我用递归实现初始数据也有我的道理,这是一般化解决方法,可以拓展到无数个方向,当然思想才是最重要的了~~ 当然,水平有限,欢迎指教哦~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值