n只蚂蚁以每秒1 cm的速度在长为L cm的杆子上爬行。当蚂蚁爬到杆子的端点上就会掉落。由于杆子太细,两只蚂蚁相遇时,他们不能交错通过,自能各自反响爬回去。对于每只蚂蚁,我们知道它距离杆子左端的距离xi, 但不知道它当前的朝向。请计算所有蚂蚁落下杆子的最短时间和最长时间。
限制条件:
1<=L <=10^6 ; 1<=n<= 10^6 ; 0<=xi<= L;
输入示例:L=10
n=3
x=2 6 7
输出示例:
min=4(左、右、右)
max=8(右、右、右)
初看到题目可能会想到要考虑每个蚂蚁的初始方向,然后枚举出蚂蚁所有可能的状态。这样做的话,在蚂蚁较少时可以,但是当蚂蚁非常多时,将会消耗大量时间,所有此方法并不合适。
仔细考虑发现:
对于最短路径:当所有蚂蚁都向着距离自己最短端行走时时间最短,而且此时蚂蚁不会相遇。
对于最长路径: 当两只蚂蚁相遇时都调头返回,设蚂蚁A和蚂蚁B,当它们相遇后把蚂蚁B当作蚂蚁A,蚂蚁A当作蚂蚁B,则可以认为蚂蚁A和蚂蚁B相遇后没有掉头仍然继续前进。根据这个思路可知每个蚂蚁都往距离自己较远的端前进就可以得到最长时间。
#include<iostream>;
#define MAX_N 1000000
using namespace std;
int L, n;
int x[MAX_N];
int minTime=0,maxTime=0;
void solve(){
cout<<"L=";
cin>>L;
cout<<"n=";
cin>>n;
cout<<"x[]=";
if(L>=1 && L<=MAX_N && n>=1 && n<= MAX_N){
for(int i=0;i<n;i++){
cin>>x[i];
if(L/2 >x[i]){
minTime=max(minTime , x[i]);
maxTime=max(maxTime , L-x[i]);
}else{
minTime=max(minTime , L-x[i]);
maxTime=max(maxTime , x[i]);
}
}
}else{
cout<<"输出有误!";
}
cout<<"min="<<minTime<<endl<<"max="<<maxTime<<endl;
}
int main(){
solve();
return 0;
}