算法:
二进制搜索,贪心算法
1 #include <iostream>
2 #include <algorithm>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <cmath>
7 #include <vector>
8 using namespace std;
9
10 const int MAXN = 50000 + 10;
11 const double EPS = 1e- 9;
12 const double PI = acos(- 1.0);
13
14 int n;
15 double l, r;
16 double x[MAXN], y[MAXN], theta[MAXN];
17
18 bool check( double ans) {
19 vector< pair< double, double> > itv;
20 for ( int i = 0; i < n; ++i) {
21 if (ans <= y[i] - EPS) {
22 itv.push_back(make_pair(
23 x[i] - tan(theta[i]) * (y[i] - ans),
24 x[i] + tan(theta[i]) * (y[i] - ans)
25 )); // get the intervals
26 }
27 }
28 sort(itv.begin(), itv.end());
29 if (itv.empty()) return 0;
30 double cur_l = itv[ 0].first, cur_r = itv[ 0].second; // get the union
31 for ( int i = 1; i < ( int)itv.size(); ++i) {
32 if (itv[i].first < cur_r + EPS) {
33 cur_r = max(cur_r, itv[i].second);
34 } else {
35 if (l > cur_l - EPS && r < cur_r + EPS) {
36 return 1;
37 }
38 cur_l = itv[i].first;
39 cur_r = itv[i].second;
40 }
41 }
42 return l > cur_l - EPS && r < cur_r + EPS;
43 }
44
45 int main() {
46 scanf( " %d%lf%lf ", &n, &l, &r);
47 for ( int i = 0; i < n; ++i) {
48 scanf( " %lf%lf%lf ", &x[i], &y[i], &theta[i]);
49 theta[i] = theta[i] / 180.0 * PI;
50 }
51
52 double low = - 1.0, high = 1000.0; // Binary Search for the answer
53 for ( int iter = 0; iter < 64; ++iter) {
54 double mid = (low + high) / 2.0;
55 if (check(mid)) {
56 low = mid;
57 } else {
58 high = mid;
59 }
60 }
61 if (low < -EPS) {
62 printf( " No Solution\n "); // Just check whether there is a solution. The test data avoid this output
63 } else {
64 printf( " %.3f\n ", (low + high) / 2.0);
65 }
66 return 0;
2 #include <algorithm>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <cstring>
6 #include <cmath>
7 #include <vector>
8 using namespace std;
9
10 const int MAXN = 50000 + 10;
11 const double EPS = 1e- 9;
12 const double PI = acos(- 1.0);
13
14 int n;
15 double l, r;
16 double x[MAXN], y[MAXN], theta[MAXN];
17
18 bool check( double ans) {
19 vector< pair< double, double> > itv;
20 for ( int i = 0; i < n; ++i) {
21 if (ans <= y[i] - EPS) {
22 itv.push_back(make_pair(
23 x[i] - tan(theta[i]) * (y[i] - ans),
24 x[i] + tan(theta[i]) * (y[i] - ans)
25 )); // get the intervals
26 }
27 }
28 sort(itv.begin(), itv.end());
29 if (itv.empty()) return 0;
30 double cur_l = itv[ 0].first, cur_r = itv[ 0].second; // get the union
31 for ( int i = 1; i < ( int)itv.size(); ++i) {
32 if (itv[i].first < cur_r + EPS) {
33 cur_r = max(cur_r, itv[i].second);
34 } else {
35 if (l > cur_l - EPS && r < cur_r + EPS) {
36 return 1;
37 }
38 cur_l = itv[i].first;
39 cur_r = itv[i].second;
40 }
41 }
42 return l > cur_l - EPS && r < cur_r + EPS;
43 }
44
45 int main() {
46 scanf( " %d%lf%lf ", &n, &l, &r);
47 for ( int i = 0; i < n; ++i) {
48 scanf( " %lf%lf%lf ", &x[i], &y[i], &theta[i]);
49 theta[i] = theta[i] / 180.0 * PI;
50 }
51
52 double low = - 1.0, high = 1000.0; // Binary Search for the answer
53 for ( int iter = 0; iter < 64; ++iter) {
54 double mid = (low + high) / 2.0;
55 if (check(mid)) {
56 low = mid;
57 } else {
58 high = mid;
59 }
60 }
61 if (low < -EPS) {
62 printf( " No Solution\n "); // Just check whether there is a solution. The test data avoid this output
63 } else {
64 printf( " %.3f\n ", (low + high) / 2.0);
65 }
66 return 0;
67 }
伪代码:
1 function verify(h)
2 Let A be a list of items, where item is a pair of numbers
3 for each source of light, s
4 if height[s] < h then ignore this source
5 else
6 base = ((Y[s] - h) * tan Z[s])
7 lx = X[s] - base
8 rx = X[s] + base
9 A.push(lx, 1)
10 A.push(rx, - 1)
11 A.push(L, 0)
12 A.push(R, 0)
13
14 sort A
15 Let cnt = 0 be number of active sources of light for the next segment
16 Let la = -infinity be the endpoint of the last seen segment
17 for i = 0 to A.size
18 Let x = A[i].first
19 Let del = A[i].second
20
21 if x > L and
22 x <= R and
23 x > la and
24 cnt == 0
25 then return " Invalid "
26
27 la = x
28 cnt += del
29 return " Valid "
2 Let A be a list of items, where item is a pair of numbers
3 for each source of light, s
4 if height[s] < h then ignore this source
5 else
6 base = ((Y[s] - h) * tan Z[s])
7 lx = X[s] - base
8 rx = X[s] + base
9 A.push(lx, 1)
10 A.push(rx, - 1)
11 A.push(L, 0)
12 A.push(R, 0)
13
14 sort A
15 Let cnt = 0 be number of active sources of light for the next segment
16 Let la = -infinity be the endpoint of the last seen segment
17 for i = 0 to A.size
18 Let x = A[i].first
19 Let del = A[i].second
20
21 if x > L and
22 x <= R and
23 x > la and
24 cnt == 0
25 then return " Invalid "
26
27 la = x
28 cnt += del
29 return " Valid "