zoukankan      html  css  js  c++  java
  • UVALive 3716 DNA Regions ——(扫描法)

      乍一看这个问题似乎是很复杂,但其实很好解决。

      先处理出每个点到原点的距离和到x正半轴的角度(从x正半轴逆时针旋转的角度)。然后以后者进行排序。

      枚举每一个点到圆心的距离,作为半径,并找出其他到圆心距离不超过这个值的点,由于他们的角度是有序的,因此线性的找出角度差最小的满足题意的两个点即可(相当于拿一个长度为k的尺子不断地移动过去)。

      那么总的复杂度为O(n^2)。

      代码如下(注意atan2的用法):

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <math.h>
     5 using namespace std;
     6 const int N = 5000 + 5;
     7 const double pi = acos(-1);
     8 
     9 int n,k;
    10 struct node
    11 {
    12     int x, y;
    13     double angle, dis;
    14     void get()
    15     {
    16         double t = x * x + y * y;
    17         //dis = sqrt(t);
    18         dis = t;
    19 
    20         angle = atan2(1.0*y, 1.0*x);
    21         /*if(y >= 0)
    22         {
    23             if(x >= 0)
    24             {
    25                 angle = asin(1.0*y / dis);
    26             }
    27             else
    28             {
    29                 angle = pi - asin(1.0*y / dis);
    30             }
    31         }
    32         else
    33         {
    34             if(x >= 0) angle = 2.0 * pi - asin(1.0*y / dis);
    35             else angle = pi + asin(1.0*y / dis);
    36         }*/
    37     }
    38     bool operator < (const node & t) const
    39     {
    40         if(fabs(angle - t.angle) < 1e-8)
    41         {
    42             return dis < t.dis;
    43         }
    44         return angle < t.angle;
    45     }
    46 }p[N];
    47 
    48 double q[N*2];
    49 
    50 int main()
    51 {
    52     int kase = 1;
    53     while(scanf("%d%d",&n,&k) == 2)
    54     {
    55         if(n == 0 && k == 0) break;
    56         for(int i=1;i<=n;i++)
    57         {
    58             scanf("%d%d",&p[i].x,&p[i].y);
    59             p[i].get();
    60         }
    61         sort(p+1,p+1+n);
    62 
    63         if(k == 0) {printf("Case #%d: 0.00
    ",kase++); continue;}
    64 
    65         double ans = 1e10;
    66         for(int i=1;i<=n;i++)
    67         {
    68             double r = p[i].dis;
    69             int num = 0;
    70             for(int j=1;j<=n;j++)
    71             {
    72                 if(p[j].dis <= r) q[++num] = p[j].angle;
    73             }
    74             if(num < k) continue;
    75             for(int j=1;j<=num;j++)
    76             {
    77                 q[j+num] = 2*pi + q[j];
    78             }
    79             for(int j=1;j<=num;j++)
    80             {
    81                 ans = min(ans, r * (q[j+k-1] - q[j]) / 2.0);
    82             }
    83         }
    84         printf("Case #%d: %.2f
    ",kase++,ans);
    85     }
    86     return 0;
    87 }
  • 相关阅读:
    python学习之控制语句
    linux中的网络基础
    python学习之准备
    linux用户权限
    python学习之函数和函数参数
    python学习之输出与文件读写
    linux中的vim编辑器的使用
    从产品和用户角度,思考需求和用户体验
    好记性不如烂笔头
    TI DaVinci(达芬奇)入门
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6730998.html
Copyright © 2011-2022 走看看