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 }