uva 10714 Ants

找规律题?YY题?

题意:给出一条线的长度L(直线在[0,L]),和蚂蚁数,下面m个数字表示m个蚂蚁的起始位置(整数,坐标),所有蚂蚁向哪边走不确定,但是两个蚂蚁相撞会掉头走。蚂蚁的速度1cm/s,蚂蚁没有长度是一个点,另外蚂蚁走到直线的两个尽头就会掉下去。问怎么走,所有蚂蚁最快掉下去,输出时间(所有蚂蚁都掉下去后再输出时间而不是第一个掉下去就输出),然后怎么走最晚掉下去,输出所有蚂蚁都掉下去的时间

这题真想不到什么算法,不过可以确定一些基本的策略

1.最快掉下去:以中点为轴,位于两端的蚂蚁都向两端走,这样他们不会发生任何的碰头,直接全部掉下去,那么最后掉下去的蚂蚁,是离中点最近的蚂蚁,它是最后掉下去的,它掉下去的时间就是所有蚂蚁都掉下去的时间

2.最慢掉下去:如果蚂蚁个数为偶数,则全部往中间收拢,期间发生相互碰撞,直到全部蚂蚁都掉下去,这样是最晚的。如果蚂蚁个数是奇数且>1,那么成对成对地取蚂蚁,从最外面开始取,每对蚂蚁都向中间靠拢,那么会剩下一个蚂蚁在最中间,它两边有两只蚂蚁,向离他远的那只移动,然后相互碰撞只到全部蚂蚁掉下去。蚂蚁个数为1,这个容易,朝离他较远的端点移动即可

 

基于上面的策略还不能解题,但是能发现想个规律

1.有m只蚂蚁,以最快方式和最慢方式走,两种方式每只蚂蚁走的路程全部加起来,刚好是m*L

2.基于上面的结论,如果有灵感,会发现用同样的方式走,但是蚂蚁相碰不掉头的话,全部加起来的路程和还是m*L

3.也就是说,掉头和不掉头是等价的?

 

最后得到这个结论,掉头和不掉头是等价,利用这个结论,可以快速找到答案

1.最快:找出最靠近中间的点,它走到离它最近的端点的时间就是全部蚂蚁掉下去的时间

2.最慢:对于每个点,找出它到两个端点的最远距离(二取一),然后在所有顶点中找一个最大值,(可以知道其实就是找最外围的点,找其中一个),它掉下去的时间就是所有蚂蚁都掉下去的时间

 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 1000010
#define INF 0x3f3f3f3f

//int a[N];
int n;

int main()
{
   int T;
   scanf("%d",&T);
   while(T--)
   {
      double len,mid;
      double a,tmp,Max;
      double Min,pos;
      scanf("%lf%d",&len,&n);
      mid=len/2;

      Max=-INF; Min=INF;
      for(int i=0; i<n; i++)
      {
         scanf("%lf",&a);
         tmp=max(a , len-a);
         Max=max(Max,tmp);
         if(fabs(mid-a) < Min)
         {
            Min=fabs(mid-a);
            pos=min(a,len-a);
         }
      }
      printf("%d %d\n",(int)pos,(int)Max);
   }
   return 0;
}

 

最后还是把这题归类在数学找规律下面吧………………

posted @ 2013-04-12 11:50  Titanium  阅读(757)  评论(0编辑  收藏  举报