有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过一只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
1. 创建C++源代码文件 ant.cpp
#include<iostream> #include<deque> using namespace std ; class AntInfo{ public: bool Orientation; //方向 int Position; //位置 }; deque<AntInfo> AntDeque; //蚂蚁信息双头队列 const int Pos[5]={3,7,11,17,23}; //蚂蚁的初始位置 int Time[32]={0}; //共有32种情况,存储每种情况的用时 int main(){ for(int i=0; i<32; ++i){ cout<<"初始位置/方向: "; for(int j=0; j<5; ++j){ AntInfo Ant; Ant.Position=Pos[j]; //初始位置赋值 Ant.Orientation=(bool)(i&(1<<j)); //初始方向赋值 AntDeque.push_front(Ant); // 5只蚂蚁信息依次压栈入双向列队 //打印5只蚂蚁初始位置和方向 cout<<Pos[j]<<'/'; if(Ant.Orientation) cout<<"右 "; else cout<<"左 "; } while(!AntDeque.empty()){ Time[i]++; //每一秒蚂蚁移动一厘米 deque<AntInfo>::iterator Pointer; //指向deque容器的迭代器,重载操作符同指针 for(Pointer=AntDeque.begin(); Pointer<AntDeque.end(); ++Pointer){ if(Pointer->Orientation) Pointer->Position++; //向右移动位置递增 else Pointer->Position--; //向左移动位置递减 } //相邻蚂蚁位置相等表示相遇,相遇两蚂蚁均改变方向 for(Pointer=AntDeque.begin(); Pointer<AntDeque.end()-1; ++Pointer){ if(Pointer->Position==(Pointer+1)->Position){ Pointer->Orientation=!Pointer->Orientation; //左蚂蚁变向 (Pointer+1)->Orientation=!(Pointer+1)->Orientation; //右蚂蚁变向 } } //判断队列首尾蚂蚁是否到达端点,剔除已经到达两端的蚂蚁 if(0==AntDeque.back().Position) AntDeque.pop_back(); //到达0点出栈 if(27==AntDeque.front().Position) AntDeque.pop_front(); //到达27点出栈 } //打印此种情况用时 cout<<" 用时:"<<Time[i]<<"秒"<<endl; } //筛选出最大最小时间并打印 int maxTime=Time[0]; int minTime=Time[0]; for(int i =1; i<32; i++){ if(Time[i]>maxTime) maxTime=Time[i]; if(Time[i]<minTime) minTime=Time[i]; } cout<<"\n最大用时:"<<maxTime<<"秒"<<endl<<"最小用时:"<<minTime<<"秒"<<endl; return 0; //main返回 }2. Linux系统环境编译和运行
2.1 如果安装gcc编译器,在命令行终端运行编译链接命令:
g++ -O3 -Wall ant.cpp -o ant.elf
2.2 如果安装clang编译器,在命令行终端运行编译链接命令:
clang++ -O3 -Wall ant.cpp -o ant.elf
2.3 命令行终端输入如下命令运行程序:
./ant.elf
2.4 结果:
xyz@xyz:/media/xyz/disk_e/Linux/posix_unix_api$ g++ -O3 -Wall ant.cpp -o ant.elf xyz@xyz:/media/xyz/disk_e/Linux/posix_unix_api$ ./ant.elf 输出的每种结果如下: 初始方向:左 左 左 左 左 用时:23秒 初始方向:右 左 左 左 左 用时:24秒 初始方向:左 右 左 左 左 用时:23秒 初始方向:右 右 左 左 左 用时:24秒 初始方向:左 左 右 左 左 用时:23秒 初始方向:右 左 右 左 左 用时:24秒 初始方向:左 右 右 左 左 用时:23秒 初始方向:右 右 右 左 左 用时:24秒 初始方向:左 左 左 右 左 用时:23秒 初始方向:右 左 左 右 左 用时:24秒 初始方向:左 右 左 右 左 用时:23秒 初始方向:右 右 左 右 左 用时:24秒 初始方向:左 左 右 右 左 用时:23秒 初始方向:右 左 右 右 左 用时:24秒 初始方向:左 右 右 右 左 用时:23秒 初始方向:右 右 右 右 左 用时:24秒 初始方向:左 左 左 左 右 用时:17秒 初始方向:右 左 左 左 右 用时:24秒 初始方向:左 右 左 左 右 用时:20秒 初始方向:右 右 左 左 右 用时:24秒 初始方向:左 左 右 左 右 用时:17秒 初始方向:右 左 右 左 右 用时:24秒 初始方向:左 右 右 左 右 用时:20秒 初始方向:右 右 右 左 右 用时:24秒 初始方向:左 左 左 右 右 用时:11秒 初始方向:右 左 左 右 右 用时:24秒 初始方向:左 右 左 右 右 用时:20秒 初始方向:右 右 左 右 右 用时:24秒 初始方向:左 左 右 右 右 用时:16秒 初始方向:右 左 右 右 右 用时:24秒 初始方向:左 右 右 右 右 用时:20秒 初始方向:右 右 右 右 右 用时:24秒 最大用时:24秒 最小用时:11秒3. 总结:
3.1. 5只蚂蚁的方向排列组合共有32中情况,方向的最简赋值方法:依次取出0~31的所有整数的二进制位 Ant.Orientation=(bool)(i & (1<<j)) ;
3.2. 每过一秒判断两两相邻的蚂蚁位置是否相等确定蚂蚁是否相遇,相遇的两只蚂蚁均改变方向;
3.3. 用双向队列deque首尾出栈的方法剔除掉到达木杆两端的蚂蚁,直到双向队列为空,记录的时间数是目标结果。