* 有一根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;
}
当然,在给出所有初始数据的实现里,由于题目只给出了两个方向,所以可以用二进制来给出哦,嘿嘿,这个能省不少时间空间呢!具体实现我不说了,有兴趣,你可以自己试试,有问题就和我探讨了~~
当然我用递归实现初始数据也有我的道理,这是一般化解决方法,可以拓展到无数个方向,当然思想才是最重要的了~~
当然,水平有限,欢迎指教哦~
百度试题讲解:蚂蚁们和木杆
最新推荐文章于 2025-08-11 10:33:03 发布