• [POJ1852] Ants(思维题)


    题干

    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.

    Example
    In:
    2
    10 3
    2 6 7
    214 7
    11 12 7 13 176 23 191
    
    Out:
    4 8
    38 207
    

    Ideas

    题意大致概括为:
    有n只蚂蚁在木棍上爬行,每只蚂蚁的速度都是每秒1单位长度,现在给你所有蚂蚁初始的位置(蚂蚁运动方向未定),蚂蚁相遇会掉头反向运动,让你求出所有蚂蚁都掉下木棍的最短时间和最长时间。

    因为能掉头,数据又足足一百万,暴搜显然是不现实的。那么怎么处理这个掉头的问题呢?让我们画个图来理解一下,看完你就会发现这都是吓唬人的。

    在这里插入图片描述
    我们以找最长时间为例,最长的时间可能出现在谁身上呢?通过看图我们知道1号蚂蚁早早下场了,所以最长时间只能出现在2或3身上。2号的路径为2、4、6(标红部分);3号的路径为3、5、7,那么,由于蚂蚁们的速度都相同,我们会发现一个很神奇的规律:
    路径1、2、3相等,路程4、5相等,但注意路程6、7不一定相等。所以呢,3号的路程可以写成1、4、7,刚好是1号蚂蚁到右端的距离对不对?同理,2号蚂蚁的路程也可以表示为3,5,6,刚好是3号蚂蚁到左端的距离对不对?以此类推,我们发现其实1,2,3号蚂蚁每个蚂蚁掉下去所走的总距离(即总时间),都能用原来的某一个蚂蚁到两端的距离表示出来(其实第二行中1号蚂蚁到左端还能走一段,但我不想改图了…),无论初始时各个蚂蚁的初方向怎样,规律是不变的。那么当蚂蚁的数量再多一点,这个规律还适用吗?

    答案是肯定的:
    在这里插入图片描述
    在这里插入图片描述
    大家可以试一试,规律依然是适用的。
    道理懂了,那么这道题就是白给了。我们直接遍历每个蚂蚁到两端的距离,根据需要取较小或较大的那个,再在所有蚂蚁中找到一个最大的(因为要求所有蚂蚁都掉下去),就是我们的答案。
    ps:这题不用开longlong,一百万的数据看着很吓人,但因为没有累加,int就够用了

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    const int maxn=1000000+10;
    int a[maxn],len,n;
    int main(){
        int t;
        cin>>t;
        while(t--){
            memset(a,0,sizeof(a));
            len=0;
            scanf("%d%d",&len,&n);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            } 
            int minn=0,maxx=0;
            for(int i=1;i<=n;i++){
                //minn=min(minn,min(a[i],len-a[i])); 注意千万不要这么写,因为我们要保证所有蚂蚁都掉下去,所以括号外是取max的
                minn=max(minn,min(a[i],len-a[i]));
                maxx=max(maxx,max(a[i],len-a[i]));
            }
            printf("%d %d
    ",minn,maxx);
        }
    }
    
  • 相关阅读:
    VS2010导入DLL的总结
    [转]C#事件简单示例
    VS2010中实现TreeView和Panel的动态更新
    【JZOJ1282】打工
    【NOIP2016提高A组五校联考2】tree
    【NOIP2016提高A组五校联考2】running
    【NOIP2016提高A组五校联考2】string
    8月~9月学习总结
    NOIP2016提高A组五校联考2总结
    NOIP2016提高A组五校联考1总结
  • 原文地址:https://www.cnblogs.com/Zfio/p/12749654.html
Copyright © 2020-2023  润新知