HDU2297 Run
以位置为横坐标,速度为纵坐标,则高处的点总会跑到低处的点前面。
如图B追上A的时间就是横坐标差除以纵坐标差,也就是说斜率的绝对值越大,追上的越快。
那么C就不会比B先追上A,B有机会保持一段时间的第一。同理C会在未来追上B,而保持一段时间第一。
由此看来,统计凸包上x最大点和y最大点之间点的个数即得答案。对于多点共线的情况,只计一次,在求凸包的时候就可以处理掉了。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<math.h> 5 #include<algorithm> 6 using namespace std; 7 typedef __int64 LL; 8 const int maxn = 111111; 9 typedef struct{LL x, y;}Point; 10 inline LL det(LL x1, LL y1, LL x2, LL y2) 11 {return x1 * y2 - x2 * y1;} 12 LL cross(Point a, Point b, Point c) 13 {return det(b.x -a.x, b.y - a.y, c.x - a.x, c.y - a.y);} 14 int CompG(const void *a, const void *b) 15 { 16 if((*(Point*)a).y - (*(Point*)b).y) 17 return (*(Point*)a).x - (*(Point*)b).x; 18 return (*(Point*)a).y - (*(Point*)b).y; 19 } 20 LL Graham(Point p[], Point res[], LL n, LL &top) 21 { 22 LL len, i; 23 top = 1; 24 qsort(p, n, sizeof(Point), CompG); 25 res[0] = p[0], res[1] = p[1]; 26 for(i = 2; i < n; ++ i) 27 { 28 while(top && cross(res[top], res[top - 1], p[i]) <= 0) 29 -- top; 30 res[++ top] = p[i]; 31 } 32 len = top; 33 res[++ top] = p[n - 2]; 34 for(i = n - 3; i >= 0; -- i) 35 { 36 while(top != len && cross(res[top], res[top - 1], p[i]) <= 0) 37 -- top; 38 res[++ top] = p[i]; 39 } 40 return top; 41 } 42 Point p[maxn], res[maxn]; 43 LL n, m; 44 int main() 45 { 46 int t, i, j, k, cnt; 47 LL maxx, maxy; 48 for(scanf("%d", &t); t -- ; ) 49 { 50 scanf("%I64d", &n); 51 for(i = 0; i < n; ++ i) 52 scanf("%I64d%I64d", &p[i].x, &p[i].y); 53 p[n] = p[0]; 54 Graham(p, res, n, m); 55 for(i = maxx = maxy = 0; i < m; ++ i) 56 { 57 if(res[i].x > res[maxx].x) maxx = i; 58 if(res[i].y > res[maxy].y) maxy = i; 59 } 60 printf("%I64d\n", (maxx - maxy + n) % n + 1); 61 } 62 return 0; 63 }