• 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 }
  • 相关阅读:
    在Ubuntu中通过update-alternatives切换软件版本
    SCons: 替代 make 和 makefile 及 javac 的极好用的c、c++、java 构建工具
    mongodb 的使用
    利用grub从ubuntu找回windows启动项
    How to Repair GRUB2 When Ubuntu Won’t Boot
    Redis vs Mongo vs mysql
    java script 的工具
    python 的弹框
    how to use greendao in android studio
    python yield的终极解释
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6730998.html
Copyright © 2020-2023  润新知