• CF613A:Peter and Snow Blower


    用一个圆心在(x,y)的圆环覆盖一个n边形,顺或逆时针给出n边形所有顶点,求圆环最小面积。

    卡了好久,各种傻逼错误。。

    题目就是让我们固定一大一小两个边界圆,我们来看看这两个圆满足什么条件。

    首先外面的那个圆肯定是经过n边形的某个顶点,所以外圆半径就是最大的点距。

    其次内圆呢,可能经过一个点,也可能与某条边相切,但注意,这里的线是线段不是直线!

    所以可能会出现最后的内圆和某条“直线”相交而与其对应的线段没有交点。例如:

    上图中内圆与四条“直线”都相交,但与“线段”只有一个交点。

    为了判断内圆,我用了最粗暴的方法--二分,计算与当前半径的圆相交的“直线“的两个交点是否在“线段”上,用横坐标或纵坐标判断。

    Trick:

    如果是用y=kx+b就会wa,因为平面上不是所有的直线都能这么表示,要用一般式Ax+By+C=0。

    计算圆与直线相交情况时记得分B是否为0的情况。所有计算过程中记得判断除0情况。

    精度。二分时在精度那里要注意R-eps或者L+eps,不然可能tle。

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstring>
      6 #include<cmath>
      7 //#include<iostream>
      8 using namespace std;
      9 
     10 int n;
     11 #define maxn 100011
     12 struct Point
     13 {
     14     double x,y;
     15 }a[maxn],P;
     16 struct Line
     17 {
     18     double a,b,c,dis;
     19 }l[maxn];
     20 const double eps=1e-10,pi=3.1415926535897932384626434;
     21 void do_line(int id,double x1,double y1,double x2,double y2)
     22 {
     23     if (x1==x2)
     24     {
     25         l[id].a=1;
     26         l[id].b=0;
     27         l[id].c=-x1;
     28     }
     29     else if (y1==y2)
     30     {
     31         l[id].a=0;
     32         l[id].b=1;
     33         l[id].c=-y1;
     34     }
     35     else if (x2*y1==x1*y2)
     36     {
     37         l[id].c=0;
     38         l[id].a=233333;
     39         if (y1) l[id].b=-x1/y1*l[id].a;
     40         else l[id].b=-x2/y2*l[id].a;
     41     }
     42     else
     43     {
     44         l[id].c=100000;
     45         l[id].a=l[id].c*(y2-y1)/(x2*y1-x1*y2);
     46         l[id].b=l[id].c*(x2-x1)/(y2*x1-y1*x2);
     47     }
     48     l[id].dis=abs(l[id].a*P.x+l[id].b*P.y+l[id].c)/sqrt(l[id].a*l[id].a+l[id].b*l[id].b);
     49 }
     50 double ppdissqr(double x1,double y1,double x2,double y2)
     51 {
     52     return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);
     53 }
     54 bool judge(double x)
     55 {
     56     for (int i=1;i<=n;i++)
     57         if (l[i].dis-x<=-eps)
     58         {
     59             double A=l[i].a,B=l[i].b,C=l[i].c;
     60             if (B)
     61             {
     62                 double delta=((A/B)*(A/B)+1)*x*x-((A*P.x+C)/B+P.y)*((A*P.x+C)/B+P.y),
     63                 x1=(-2*(A/B*(C/B+P.y)-P.x)+sqrt(delta))/(2*(1+(A/B)*(A/B))),
     64                 x2=(-2*(A/B*(C/B+P.y)-P.x)-sqrt(delta))/(2*(1+(A/B)*(A/B)));
     65                 double p=a[i].x,q=a[i+1].x;
     66                 if (i==n) q=a[1].x;
     67                 if (p>q) swap(p,q);
     68                 if ((x1>=p && x1<=q)
     69                 || (x2>=p && x2<=q))
     70                 return 0;
     71             }
     72             else
     73             {
     74                 double y1=P.y+sqrt(x*x-(-C/A-P.x)*(-C/A-P.x)),
     75                        y2=P.y-sqrt(x*x-(-C/A-P.x)*(-C/A-P.x));
     76                 double p=a[i].y,q=a[i+1].y;
     77                 if (i==n) q=a[1].y;
     78                 if (p>q) swap(p,q);
     79                 if ((y1>=p && y1<=q)
     80                 || (y2>=p && y2<=q))
     81                 return 0;
     82             }
     83         }
     84     return 1;
     85 }
     86 int main()
     87 {
     88     scanf("%d%lf%lf",&n,&P.x,&P.y);
     89     for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
     90     for (int i=1;i<n;i++)
     91         do_line(i,a[i].x,a[i].y,a[i+1].x,a[i+1].y);
     92     do_line(n,a[n].x,a[n].y,a[1].x,a[1].y);
     93     double f1=0.0,r2,L=0.0,R;
     94     for (int i=1;i<=n;i++)
     95         f1=max(f1,ppdissqr(a[i].x,a[i].y,P.x,P.y));
     96     R=sqrt(f1);
     97     for (int i=1;i<=n;i++)
     98         R=min(R,sqrt(ppdissqr(a[i].x,a[i].y,P.x,P.y)));
     99     while (R-L>eps)
    100     {
    101         double mid=(L+R+eps)/2;
    102         if (judge(mid)) L=mid;
    103         else R=mid-eps;
    104     }
    105     r2=(L+R)/2;
    106     printf("%.10lf
    ",pi*(f1-r2*r2));
    107     return 0;
    108 }
    View Code
  • 相关阅读:
    erlang中变量作用域
    erlang数字转字符串
    gen_server笔记
    Using Eredis, Redis With Erlang
    erlang lists模块函数使用大全
    erlang抽象码与basho的protobuf
    Erlang Module and Function
    Erlang中频繁发送远程消息要注意的问题
    Erlang中的record与宏
    数据结构之数羊问题
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7193262.html
Copyright © 2020-2023  润新知