HDU4439_No place to hide 2012 ICPC Tianjin Site I 题

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

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

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

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

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 }
posted @ 2012-10-26 16:39  CSGrandeur  阅读(1221)  评论(0编辑  收藏  举报