这是POJ上的一道算法题目,不算太难,主要是需要换一个角度分析问题,即挖掘问题的本质,从另一个角度简化问题。
原理如下:
初看题目似乎有些困难,但是可以讲两个相遇的蚂蚁之后的行为理解为没有折返,因此针对最长时间的策略应该是选择每个蚂蚁朝最远端行走,然后取其中值最大的时间作为输出;最短时间相对简单些,每只蚂蚁朝最近端走,也不会出现两两相遇的情况,然后找其中时间最大者作为输出。
本题的主要收获:
这里给出两种代码,可以看到用基本一致,但是使用的输入输出操作使用不同的方式,第一种采用scanf和printf格式化输入输出,而cin和cout流输入输出,直观的效果上前者要快许多,大概能提升4到5倍。也就是说scanf的效率要高于cin这也是本题的一大收获:相同的操作使用不同的工具(函数等)会带来不同的效率。往往在求解问题和设计算法的时候,容易专注于算法本身的时间复杂度和空间复杂度。这没有错,也是主要的考查方面。但是好的时间复杂度的算法设计出来后,接下来要做的就是实现它。此时考查的就是我们的编程能力,也就是一些细节问题,同样的意思,可能只需一两句或者使用更快捷的方法就能解决。
所以在日常的练习中应该注意从两个方面提升程序的运行性能:
一.通常所指的算法设计,一步一步的降低算法的时间复杂度
二.编程细节,用高效简洁的代码完成一样原理的算法。
代码如下:
使用scanf和printf的代码,时间157Ms
#include<iostream>
#include<algorithm>
using namespace std;
//const int Max_n=1000001;
//int pos_ant[Max_n];
//int times[Max_n][2];
int main()
{
int cases,Length,n,pos_ant,early,last,tempmin,tempmax;
cin>>cases;
while(cases--){
scanf("%d %d",&Length,&n);
//cin>>Length>>n;
early=0,last=0;
for(int i=0;i!=n;i++){
scanf("%d",&pos_ant);
//cin>>pos_ant;
tempmin=pos_ant; tempmax=Length-pos_ant;
if(tempmin>tempmax)
swap(tempmin,tempmax);
early=max(early,tempmin);
last=max(last,tempmax);
}
printf("%d %d\n",early,last);
//cout<<early<<' '<<last<<endl;
}
return 0;
}
使用cout和cin的代码,时间625Ms
#include<iostream>
#include<algorithm>
using namespace std;
//const int Max_n=1000001;
//int pos_ant[Max_n];
//int times[Max_n][2];
int main()
{
int cases,Length,n,pos_ant,early,last,tempmin,tempmax;
cin>>cases;
while(cases--){
cin>>Length>>n;
early=0,last=0;
for(int i=0;i!=n;i++){
cin>>pos_ant;
tempmin=pos_ant; tempmax=Length-pos_ant;
if(tempmin>tempmax)
swap(tempmin,tempmax);
early=max(early,tempmin);
last=max(last,tempmax);
}
cout<<early<<' '<<last<<endl;
}
return 0;
}