[0928][Clover8]Rainbow的密码

算法:

二进制搜索,贪心算法

 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< doubledouble> > 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 "

转载于:https://www.cnblogs.com/shy-/archive/2012/09/28/2707719.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值