HDU4439_No place to hide 2012 ICPC Tianjin Site I 题

难道和 I 题这么有缘么?长春也是 I 题……

1、如果有某个追逐点的速度大于目标点,或者位置与目标点重合,则答案为1;

2、追逐点速度不大于目标点时,目标点有一个方向上的圆周区间可以被追到,计算这个区间的范围;

HDU4439_No place to hide 2012 ICPC Tianjin Site I 题

到两点距离成比例的点轨迹是圆,用圆求切线应该也能做。

3、转化为最小区间覆盖,因为在圆周上,所以枚举一下起点,总复杂度O(Nlogn+N^2)=O(N^2)

比赛时候脑子抽了,竟然忘了区间覆盖怎么写!最后十分钟没调出来。若是有这一题,应该就稳进Final了吧。

  1 #include<stdio.h>

  2 #include<string.h>

  3 #include<stdlib.h>

  4 #include<math.h>

  5 #include<algorithm>

  6 using namespace std;

  7 const int maxn = 1011;

  8 const double eps = 1e-8;

  9 const double pi = acos(-1.0);

 10 inline double dcmp(double x) {return (x > eps) - (x < -eps);}

 11 inline double Sqr(double x) {return x * x;}

 12 struct Point

 13 {

 14     double x, y, v;

 15     Point(){}

 16     Point(double x_, double y_){x = x_, y = y_;}

 17     double Dis(Point &b){return sqrt(Sqr(x - b.x) + Sqr(y - b.y));}

 18 };

 19 Point p[maxn], th;

 20 int n;

 21 void AngManage(double &x)

 22 {

 23     while(x + pi < -eps) x += pi + pi;

 24     while(x - pi > -eps) x -= pi + pi;

 25 }

 26 inline double CounterAng(double s, double e)

 27 {return e > s + eps ? e - s : pi + pi + e - s;}

 28 struct Cov

 29 {

 30     double s, e;

 31     void Read(double s_, double e_)

 32     {

 33         AngManage(s_), AngManage(e_);

 34         s = s_, e = e_;

 35     }

 36     bool operator<(const Cov &b)const

 37     {

 38         if(!dcmp(s - b.s)) return CounterAng(s, e) > CounterAng(b.s, b.e);

 39         return s < b.s;

 40     }

 41 } cover[maxn], cc[maxn];

 42 int main()

 43 {

 44     int t, i, j, k, ans, cnt;

 45     bool flag;

 46     for(scanf("%d", &t); t --; )

 47     {

 48         flag = false;

 49         scanf("%d", &n);

 50         scanf("%lf%lf%lf", &th.v, &th.x, &th.y);

 51         for(i = 0; i < n; ++ i)

 52         {

 53             scanf("%lf%lf%lf", &p[i].v, &p[i].x, &p[i].y);

 54             if(p[i].v > th.v + eps || !dcmp(p[i].Dis(th))) flag = true;

 55         }

 56         if(flag) {printf("1\n"); continue;}

 57         if(!dcmp(th.v)) {printf("0\n"); continue;}

 58         for(i = 0; i < n; ++ i)

 59         {

 60             double ang = atan2(p[i].y - th.y, p[i].x - th.x);

 61             if(p[i].v > th.v - eps)

 62             {

 63                 cover[i].Read(ang - pi * 0.5, ang + pi * 0.5);

 64                 continue;

 65             }

 66             double c = p[i].Dis(th);

 67             double T = sqrt(Sqr(c) / (Sqr(th.v) - Sqr(p[i].v)));

 68             double cs = acos(c / T / th.v);

 69             cover[i].Read(ang - cs, ang + cs);

 70         }

 71         sort(cover, cover + n);

 72         for(i = k = 1; i < n; ++ i)

 73             if(dcmp(cover[i].s - cover[i - 1].s)) cover[k ++] = cover[i];

 74         n = k;

 75         for(i = 0, ans = 0x3f3f3f3f; i < n; ++ i)

 76         {

 77             for(j = i, k = 0; ; j = (j + 1) % n)

 78             {

 79                 cc[k].Read(cover[j].s - cover[i].s - pi, cover[j].e - cover[i].s - pi);

 80                 if(cc[k].s > cc[k].e) cc[k].e = pi + pi;

 81                 ++ k;

 82                 if(j == (i + n - 1) % n) break;

 83             }

 84             double now = -pi - pi, nex = -pi;

 85             flag = false;

 86             for(j = cnt = 0; j < n; ++ j)

 87             {

 88                 if(cc[j].e < now + eps) continue;

 89                 if(cc[j].s > nex + eps) break;

 90                 if(cc[j].s > now + eps)

 91                 {

 92                     ++ cnt;

 93                     now = nex;

 94                 }

 95                 if(cc[j].e > nex + eps) nex = cc[j].e;

 96                 if(nex > pi - eps) {flag = true; break;}

 97             }

 98             if(flag) ans = min(ans, cnt);

 99         }

100         if(ans == 0x3f3f3f3f) ans = 0;

101         printf("%d\n", ans);

102     }

103     return 0;

104 }

你可能感兴趣的:(ICPC)