题目大意:

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

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

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

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

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

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

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

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

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

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

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

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 105
#define eps 1e-9 int dcmp(double x)
{
if(fabs(x)<eps) return ;
return x<?-:;
} struct Point{
double x , y;
Point(double x= , double y=):x(x),y(y){}
void input(){scanf("%lf%lf" , &x , &y);}
double dis(Point m){
return (x-m.x)*(x-m.x)+(y-m.y)*(y-m.y);
}
}p[N] , poly[N]; typedef Point Vector; struct Line{
Point p;
Vector v;
double ang;
Line(){}
Line(Point p , Vector v):p(p),v(v){ang = atan2(v.y , v.x);}
bool operator<(const Line &m) const{
return dcmp(ang-m.ang)<;
}
}line[N]; Vector operator+(Vector a , Vector b){return Vector(a.x+b.x , a.y+b.y);}
Vector operator-(Vector a , Vector b){return Vector(a.x-b.x , a.y-b.y);}
Vector operator*(Vector a , double b){return Vector(a.x*b , a.y*b);}
Vector operator/(Vector a , double b){return Vector(a.x/b , a.y/b);} double Cross(Vector a , Vector b){return a.x*b.y-a.y*b.x;}
double Dot(Vector a , Vector b){return a.x*b.x+a.y*b.y;}
double Len(Vector a){return sqrt(Dot(a , a));} Vector Normal(Vector a)
{
double l = Len(a);
return Vector(-a.y , a.x)/l;
} bool OnLeft(Line L , Point p)
{
return dcmp(Cross(L.v , p-L.p))>=;
} Point GetIntersection(Line a , Line b)
{
Vector u = a.p-b.p;
double t = Cross(b.v , u)/Cross(a.v , b.v);
return a.p+a.v*t;
} int HalfplaneIntersection(Line *L , int n , Point *poly)
{
sort(L , L+n);
int first , last;
Point *p = new Point[n];
Line *q = new Line[n];
q[first=last=]=L[];
for(int i= ; i<n ; i++){
while(first<last && !OnLeft(L[i] , p[last-])) last--;
while(first<last && !OnLeft(L[i] , p[first])) first++;
q[++last] = L[i];
if(fabs(Cross(q[last].v , q[last-].v))<eps){
last--;
if(OnLeft(q[last] , L[i].p)) q[last] = L[i];
}
if(first<last) p[last-] = GetIntersection(q[last-] , q[last]);
}
while(first<last && !OnLeft(q[first] , p[last-])) last--;
if(last-first<=) return ;
p[last] = GetIntersection(q[last] , q[first]);
int m= ;
for(int i=first ; i<=last ; i++) poly[m++] = p[i];
return m;
} int n;
double r; int main()
{
// freopen("in.txt" , "r" , stdin);
while(~scanf("%d%lf" , &n , &r)){
for(int i= ; i<n ; i++) p[i].input();
p[n] = p[];
for(int i= ; i<n ; i++){
Vector v = p[i]-p[i+];
Vector t = Normal(v)*r;
line[i] = Line(p[i]+t , v);
}
int k = HalfplaneIntersection(line , n , poly);
Point p1=poly[] , p2=poly[];
double maxn = ;
// for(int i=0 ; i<k ; i++) cout<<poly[i].x<<" "<<poly[i].y<<endl;
for(int i= ; i<k ; i++){
for(int j= ; j<k ; j++){
if(poly[i].dis(poly[j])-maxn>eps){
p1 = poly[i] , p2 = poly[j];
maxn = poly[i].dis(poly[j]);
}
}
}
printf("%.4f %.4f %.4f %.4f\n" , p1.x , p1.y , p2.x , p2.y);
}
return ;
}

POJ 3384的更多相关文章

  1. poj 3384 半平面交

    Feng Shui Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 5183   Accepted: 1548   Speci ...

  2. POJ 3384 Feng Shui

    http://poj.org/problem?id=3384 题意:给一个凸包,求往里面放两个圆(可重叠)的最大面积时的两个圆心坐标. 思路:先把凸包边往内推R,做半平面交,然后做旋转卡壳,此时得到最 ...

  3. poj 3384 Feng Shui (Half Plane Intersection)

    3384 -- Feng Shui 构造半平面交,然后求凸包上最远点对. 这题的题意是给出一个凸多边形区域,要求在其中放置两个半径为r的圆(不能超出凸多边形区域),要求求出两个圆心,使得多边形中没有被 ...

  4. POJ 3384 Feng Shui --直线切平面

    题意:房间是一个凸多边形,要在里面铺设两条半径为r的圆形地毯,可以重叠,现在要求分别铺设到哪,使地毯所占的地面面积最大. 解法:要使圆形地毯所占面积最大,圆形地毯一定是与边相切的,这样才能使尽量不重叠 ...

  5. POJ 3384 Feng Shui(半平面交向内推进求最远点对)

    题目链接 题意 : 两个圆能够覆盖的最大多边形面积的时候两个圆圆心的坐标是多少,两个圆必须在多边形内. 思路 : 向内推进r,然后求多边形最远的两个点就是能覆盖的最大面积. #include < ...

  6. POJ 3384 Feng Shui 半平面交

    题目大意:一个人很信"Feng Shui",他要在房间里放两个圆形的地毯. 这两个地毯之间可以重叠,可是不能折叠,也不能伸到房间的外面.求这两个地毯可以覆盖的最大范围.并输出这两个 ...

  7. POJ 3384 Feng Shui 凸包直径 + 半平面交

    G++一直没有过了 换成 C++果断A掉了...It's time to bet RP. 题意:给一个多边形,然后放进去两个圆,让两个圆的覆盖面积尽量最大,输出两个圆心的坐标. 思路:将多边形的边向里 ...

  8. POJ 3384 放地毯【半平面交】

    <题目链接> 题目大意: 给出一个凸多边形的房间,根据风水要求,把两个圆形地毯铺在房间里,不能折叠,不能切割,可以重叠.问最多能覆盖多大空间,输出两个地毯的圆心坐标.多组解输出其中一个,题 ...

  9. POJ 3384 Feng Shui (半平面交)

    Feng Shui Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3743   Accepted: 1150   Speci ...

随机推荐

  1. supervisord

    [简介] supervisord的官网:http://supervisord.org.看懂英文的可以不用看我的博客,直接看文档就行了,文档写得非常好.点个赞!! Supervisor是一个客户/服务器 ...

  2. Android:控件WebView显示网页

    WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要 ...

  3. hdu5785(极角排序求所有锐角钝角个数)

    做法很显然,求出所有的锐角和钝角就能求出有多少个锐角三角形了. 我用了愚钝的方法,写了两三个小时... 看了下别人简单的代码.学习了下做法. sort(temp+,temp+cnt+);//排序 Fo ...

  4. ltib学习抄录

    linux -- LTIB学习笔记 一 安装篇二 运行篇三 修改工具包 四 编译新的内核 ---------相关资料------------------------------------------ ...

  5. python操作mongodb之五大量写操作

    import pymongo #库名 db = pymongo.MongoClient('192.168.30.252',27017).bulk_example #test集合插入 db.test.i ...

  6. java 基础(第一天)

    1.  一个文件里面只能有一个 public 修饰的方法   且方法名与文件名保持一致. 如: public class main(){ } class car(){ } class dog(){ } ...

  7. centos7 使用 omnibus包安装方式,安装 gitlab7.4

    centos7 使用 omnibus包安装方式,安装 gitlab7.4 1: gitlab是一个开源的软件,类似于github.com那样的git代码管理仓库: 官网 https://about.g ...

  8. 【bzoj3625】【xsy1729】小朋友和二叉树

    [bzoj3625]小朋友与二叉树 题意 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有 ...

  9. Bootstrap标签

    Bootstrap是Twitter推出的一个用于前端开发的开源工具包.用外链加载的方式可以将Bootstrap链接进来 常用方式: <link rel="stylesheet" ...

  10. canvas调节视频颜色

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...