POJ 1852 Ants 蚂蚁

来源:互联网 发布:linux启动php服务命令 编辑:程序博客网 时间:2024/04/29 03:05
Ants
Time Limit: 1000MS
Memory Limit: 30000KTotal Submissions: 6440
Accepted: 3023

Description

An army of ants walk on a horizontal pole of length l cm, each with a constant speed of 1 cm/s. When a walking ant reaches an end of the pole, it immediatelly falls off it. When two ants meet they turn back and start walking in opposite directions. We know the original positions of ants on the pole, unfortunately, we do not know the directions in which the ants are walking. Your task is to compute the earliest and the latest possible times needed for all ants to fall off the pole.

Input

The first line of input contains one integer giving the number of cases that follow. The data for each case start with two integer numbers: the length of the pole (in cm) and n, the number of ants residing on the pole. These two numbers are followed by n integers giving the position of each ant on the pole as the distance measured from the left end of the pole, in no particular order. All input integers are not bigger than 1000000 and they are separated by whitespace.

Output

For each case of input, output two numbers separated by a single space. The first number is the earliest possible time when all ants fall off the pole (if the directions of their walks are chosen appropriately) and the second number is the latest possible such time.

Sample Input

210 32 6 7214 711 12 7 13 176 23 191

Sample Output

4 838 207    在一本书上看到的这道题,由于每只蚂蚁朝向不知道,所以可以想到穷竭搜索,时间复杂度为O(2^n),n的规模是1000000,显然穷竭搜索思路不可取。    接下来,让我们考虑比穷竭搜索更高效的算法。首先,对于最短时间,看起来所有蚂蚁都朝向较近的端点走比较好。事实上,这种情况下不会发生两只蚂蚁相遇的情况,而且也不可能在比此更短的时间内走到竿子的端点。(这种情况下,我们要求所有蚂蚁都落下时最短的时间,即只要求当所有蚂蚁以最短时间落下时最后一只蚂蚁落下的时间,而每只蚂蚁至少要走到端点即朝较近端点走,并且这种走法不会导致两蚂蚁相撞。)    接下来,为了思考最长时间的情况,当两只蚂蚁相遇时会发生什么?两只蚂蚁相遇后反向走,如果无视不同蚂蚁的区别,可以以为是保持原方向交错而过。(这里,要考虑所有蚂蚁都掉落时的时间,所以可以无视不同蚂蚁的区别。)这样看来,可以以为每只蚂蚁都是独立运动的,所以要求最长时间,只要求蚂蚁到竿子端点的最大距离。    这样,无论最长时间还是最短时间,都只要对每只蚂蚁检查一次就好了,这是O(n)时间的算法。对于限制条件n<=10^6,这个算法完全可以在1s内完成。    书上说,这是考察想象力类型问题的经典例子。有很多这样的问题,虽然开始不太明白,但想通之后,最后的程序却是出乎意料的简单。    最后一点,输入规模为1000000,所以虽然用c++,为节省时间输入用scanf();(这是超不超时的区别)#include <iostream>#include <stdio.h>using namespace std;typedef struct A{    int s;    int e;}Ant;Ant a[1000005];int main(){    int l,n,i,t;    int tmp,max1,min1;    cin>>t;    while(t--)    {        cin>>l>>n;        for(i=1;i<=n;i++)        {            scanf("%d",&a[i].s);            a[i].e=l-a[i].s;            if(a[i].s>a[i].e)            {                tmp=a[i].s;                a[i].s=a[i].e;                a[i].e=tmp;            }        }        min1=0;        max1=0;        for(i=1;i<=n;i++)        {            if(min1<a[i].s)                min1=a[i].s;            if(max1<a[i].e)                max1=a[i].e;        }        cout<<min1<<" "<<max1<<endl;    }    return 0;}1 
原创粉丝点击