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 }
posted @ 2012-09-10 00:56  CSGrandeur  阅读(619)  评论(0编辑  收藏  举报