找规律题?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; }
最后还是把这题归类在数学找规律下面吧………………