zoukankan      html  css  js  c++  java
  • POJ 3384

     题目大意:

    给定一个多边形,给定一个圆的半径,要求在多边形中放置两个同样半径的圆,可相互覆盖,但不能超出多边形的范围,希望两个圆的面积覆盖和最大

    输出任意一组满足的圆的圆心点

    如果两个圆不相互覆盖,那么必然达到最大面积

    如果相互覆盖,可以换一种方式考虑,因为两个圆是一样的,两个圆的距离越长,那么相互覆盖的面积必然越小

    所以可以将多边形内推进半径的长度

    然后在半平面交后得到的多边形中找到距离最远的两个点

    仔细想一想可以知道多边形上最远距离的点,必然是两个顶点的距离

    所以平方的方法就可以求解了

    当然用旋转卡壳的话在n的复杂度内就可以完美解决也是可行的

    这里就用第一种简单的方法了

    这里感觉精度卡的比较严,之前没写dcmp就一直过不了,尝试着加了一些精确度判断就a了

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <algorithm>
      5 #include <cmath>
      6 using namespace std;
      7 #define N 105
      8 #define eps 1e-9
      9 
     10 int dcmp(double x)
     11 {
     12     if(fabs(x)<eps) return 0;
     13     return x<0?-1:1;
     14 }
     15 
     16 struct Point{
     17     double x , y;
     18     Point(double x=0 , double y=0):x(x),y(y){}
     19     void input(){scanf("%lf%lf" , &x , &y);}
     20     double dis(Point m){
     21         return (x-m.x)*(x-m.x)+(y-m.y)*(y-m.y);
     22     }
     23 }p[N] , poly[N];
     24 
     25 typedef Point Vector;
     26 
     27 struct Line{
     28     Point p;
     29     Vector v;
     30     double ang;
     31     Line(){}
     32     Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
     33     bool operator<(const Line &m) const{
     34         return dcmp(ang-m.ang)<0;
     35     }
     36 }line[N];
     37 
     38 Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
     39 Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
     40 Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
     41 Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);}
     42 
     43 double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
     44 double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;}
     45 double Len(Vector a){return sqrt(Dot(a , a));}
     46 
     47 Vector Normal(Vector a)
     48 {
     49     double l = Len(a);
     50     return Vector(-a.y , a.x)/l;
     51 }
     52 
     53 bool OnLeft(Line L , Point p)
     54 {
     55     return dcmp(Cross(L.v , p-L.p))>=0;
     56 }
     57 
     58 Point GetIntersection(Line a , Line b)
     59 {
     60     Vector u = a.p-b.p;
     61     double t = Cross(b.v , u)/Cross(a.v , b.v);
     62     return a.p+a.v*t;
     63 }
     64 
     65 int HalfplaneIntersection(Line *L , int n , Point *poly)
     66 {
     67     sort(L , L+n);
     68     int first , last;
     69     Point *p = new Point[n];
     70     Line *q = new Line[n];
     71     q[first=last=0]=L[0];
     72     for(int i=1 ; i<n ; i++){
     73         while(first<last && !OnLeft(L[i] , p[last-1])) last--;
     74         while(first<last && !OnLeft(L[i] , p[first])) first++;
     75         q[++last] = L[i];
     76         if(fabs(Cross(q[last].v , q[last-1].v))<eps){
     77             last--;
     78             if(OnLeft(q[last] , L[i].p)) q[last] = L[i];
     79         }
     80         if(first<last) p[last-1] = GetIntersection(q[last-1] , q[last]);
     81     }
     82     while(first<last && !OnLeft(q[first] , p[last-1])) last--;
     83     if(last-first<=1) return 0;
     84     p[last] = GetIntersection(q[last] , q[first]);
     85     int m=0 ;
     86     for(int i=first ; i<=last ; i++) poly[m++] = p[i];
     87     return m;
     88 }
     89 
     90 int n;
     91 double r;
     92 
     93 int main()
     94 {
     95   //  freopen("in.txt" , "r" , stdin);
     96     while(~scanf("%d%lf" , &n , &r)){
     97         for(int i=0 ; i<n ; i++) p[i].input();
     98         p[n] = p[0];
     99         for(int i=0 ; i<n ; i++){
    100             Vector v = p[i]-p[i+1];
    101             Vector t = Normal(v)*r;
    102             line[i] = Line(p[i]+t , v);
    103         }
    104         int k = HalfplaneIntersection(line , n , poly);
    105         Point p1=poly[0] , p2=poly[0];
    106         double maxn = 0;
    107      //   for(int i=0 ; i<k ; i++) cout<<poly[i].x<<" "<<poly[i].y<<endl;
    108         for(int i=0 ; i<k ; i++){
    109             for(int j=0 ; j<k ; j++){
    110                 if(poly[i].dis(poly[j])-maxn>eps){
    111                     p1 = poly[i] , p2 = poly[j];
    112                     maxn = poly[i].dis(poly[j]);
    113                 }
    114             }
    115         }
    116         printf("%.4f %.4f %.4f %.4f
    " , p1.x , p1.y , p2.x , p2.y);
    117     }
    118     return 0;
    119 }
  • 相关阅读:
    JWPlayer Uncaught Error: Invalid SRT file
    京东电商API
    map, string 强大的STL
    VFL演示样例
    sizeof小览
    Java中httpClient中三种超时设置
    Windows下Mysql5.6启用监控执行脚本的日志
    实时监控MySql状态
    实时监控mysql数据库变化
    SVN命令使用详解
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4669097.html
Copyright © 2011-2022 走看看