Question link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 5033

Solution Report: There are n buildings on the X axis, each building has a height of H, and now there are Q queries. The query content is assumed that a person is standing at the position of Xi, he asked him how much angle he was looking at the sky.

The data volume is relatively large, N and q are both 10 ^ 5, but because Q is a query operation and online update and query are not required, we want to use offline algorithms, first, all the input is received, and then the final output result is calculated offline.

The idea is to sort all buildings in descending order of height, and then sort all queries in descending order of X, then, we can use a building to update each person's building. One building can only update the angle of one person's side. When it cannot be updated, we will launch this update to retrieve the next building to update all people. In theory, the number of people that can be updated in each building will become fewer and fewer, so it will not time out.

1 # include <cstdio> 2 # include <iostream> 3 # include <algorithm> 4 # include <cstring> 5 # include <cmath> 6 using namespace STD; 7 const int maxn = 100005; 8 const double Pi = ACOs (-1.0); 9 struct node 10 {11 double X, H; 12} building [maxn]; 13 struct node 14 {15 double X, left, right; 16 int ci; 17} men [maxn]; 18 bool cmpb (node A, Node B) 19 {20 if (. h! = B. h) 21 return. h> B. h; 22 else return. x <B. x; 23} 24 bool cmpm (node A, Node B) 25 {26 return. x <B. x; 27} 28 bool cmpci (node A, Node B) 29 {30 return. CI <B. CI; 31} 32 int find (Double X, int L, int R) 33 {34 while (L <r) 35 {36 int mid = (L + r)> 1; 37 If (MEN [Mid]. x> = x) 38 R = mid; 39 else l = Mid + 1; 40} 41 return l; 42} 43 44 double zhuanhua (double A, double B) 45 {46 Double temp = pi-(atan (A) + atan (B); 47 temp = 180.0 * temp/PI; 48 return temp; 49} 50 int main () 51 {52 int T, Kase = 1, n, Q; 53 scanf ("% d", & T); 54 while (t --) 55 {56 scanf ("% d", & N); 57 for (INT I = 1; I <= N; ++ I) 58 scanf ("% lf", & Building [I]. x, & Building [I]. h); 59 scanf ("% d", & Q); 60 for (INT I = 1; I <= Q; ++ I) 61 {62 scanf ("% lf", & men [I]. x); 63 men [I]. ci = I; 64 men [I]. left = men [I]. right = 0; 65} 66 sort (Building + 1, building + n + 1, cmpb); 67 sort (Men + 1, men + q + 1, cmpm ); 68 for (INT I = 1; I <= N; ++ I) 69 {70 int M = find (building [I]. x, 1, q + 1); // The first M is greater than the X position 71 // printf ("m = % d \ n", M ); 72 ///// scan to the right first 73 int r = m; 74 while (r <= q) 75 {76 Double K = building [I]. h/(MEN [R]. x-building [I]. x); 77 If (k> men [R]. right) 78 men [R ++]. right = K; 79 else break; 80} 81 int L = m-1; 82 while (L> = 1) 83 {84 Double K = building [I]. h/(building [I]. x-Men [l]. x); 85 if (k> men [l]. left) 86 men [l --]. left = K; 87 else break; 88} 89} 90 sort (Men + 1, men + q + 1, cmpci); 91 printf ("case # % d: \ n ", Kase ++); 92 for (INT I = 1; I <= Q; ++ I) 93 printf (" %. 10lf \ n ", zhuanhua (MEN [I]. left, men [I]. right); 94} 95 return 0; 96} 97/* 98 33 99 5100 1 2101 3 3102 5 1103 7 4104 9 2105 4106 2107 4108 6109 8110 */

View code

HDU 5033 Building