POJ 1852 Ants(模拟+弹性碰撞)

原题地址

http://poj.org/problem?id=1852

题意:在一根长为L厘米的水平木棍上有n只蚂蚁,它们以每秒1cm/s的速度走到木棍一端就会掉下去。现在知道它们起始位置(相对于木棍左端点的距离)。但是不知道它们爬行的方向。两只蚂蚁相遇后,它们会掉头往反方向走。求所有蚂蚁都落下木棍的最短时间和最长时间。

解题思路

如果采用穷举搜索的办法枚举所有蚂蚁的初始朝向,那么复杂度为O(2^n),当n在百万数量级时,运行时间无法想象。对算法优化如下:

  • 对于最短时间,显然当所有蚂蚁都朝离自己最近的端点前进时,总时间最短,但必须满足所有蚂蚁都掉下去,所以要取所有蚂蚁到最近端距离的最大值

  • 对于最长时间,题目中描述的两只蚂蚁相遇后掉头这种行为,本质上对时间没有影响,只要忽略两只蚂蚁的区别就可以看作各自保持原样前进。因此可以要让蚂蚁都朝向离自己最远的端点,取所有蚂蚁到最远端点距离的最大值即可。(实际上只需要看最两侧的蚂蚁,但是排序会增加复杂度)

AC代码

#include 
#include 
using namespace std;

const int maxn = 1000005;
int pos[maxn];

int main()
{
    int kase, length, n;
    cin >> kase;
    while (kase--)
    {
        cin >> length >> n;
        for (int i = 0; icin >> pos[i];
        //计算最短时间,所有蚂蚁朝最近端点的方向
        int minT = 0;
        for (int i = 0; i//注意取max保证所有都掉下去
            minT = max( minT, min(pos[i], length-pos[i]) );

        //计算最长时间,所有蚂蚁朝向最远端点的方向
        int maxT = 0;
        for (int i = 0; icout << minT << ' ' << maxT << endl;
    }
    return 0;
}

算法复杂度:O(n)
耗时:610ms(估计测试的n较大)

你可能感兴趣的:(算法与数据结构,POJ,基础练习,思维题)