POJ 3384
题目大意:
给定一个多边形,给定一个圆的半径,要求在多边形中放置两个同样半径的圆,可相互覆盖,但不能超出多边形的范围,希望两个圆的面积覆盖和最大
输出任意一组满足的圆的圆心点
如果两个圆不相互覆盖,那么必然达到最大面积
如果相互覆盖,可以换一种方式考虑,因为两个圆是一样的,两个圆的距离越长,那么相互覆盖的面积必然越小
所以可以将多边形内推进半径的长度
然后在半平面交后得到的多边形中找到距离最远的两个点
仔细想一想可以知道多边形上最远距离的点,必然是两个顶点的距离
所以平方的方法就可以求解了
当然用旋转卡壳的话在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的更多相关文章
- poj 3384 半平面交
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5183 Accepted: 1548 Speci ...
- POJ 3384 Feng Shui
http://poj.org/problem?id=3384 题意:给一个凸包,求往里面放两个圆(可重叠)的最大面积时的两个圆心坐标. 思路:先把凸包边往内推R,做半平面交,然后做旋转卡壳,此时得到最 ...
- poj 3384 Feng Shui (Half Plane Intersection)
3384 -- Feng Shui 构造半平面交,然后求凸包上最远点对. 这题的题意是给出一个凸多边形区域,要求在其中放置两个半径为r的圆(不能超出凸多边形区域),要求求出两个圆心,使得多边形中没有被 ...
- POJ 3384 Feng Shui --直线切平面
题意:房间是一个凸多边形,要在里面铺设两条半径为r的圆形地毯,可以重叠,现在要求分别铺设到哪,使地毯所占的地面面积最大. 解法:要使圆形地毯所占面积最大,圆形地毯一定是与边相切的,这样才能使尽量不重叠 ...
- POJ 3384 Feng Shui(半平面交向内推进求最远点对)
题目链接 题意 : 两个圆能够覆盖的最大多边形面积的时候两个圆圆心的坐标是多少,两个圆必须在多边形内. 思路 : 向内推进r,然后求多边形最远的两个点就是能覆盖的最大面积. #include < ...
- POJ 3384 Feng Shui 半平面交
题目大意:一个人很信"Feng Shui",他要在房间里放两个圆形的地毯. 这两个地毯之间可以重叠,可是不能折叠,也不能伸到房间的外面.求这两个地毯可以覆盖的最大范围.并输出这两个 ...
- POJ 3384 Feng Shui 凸包直径 + 半平面交
G++一直没有过了 换成 C++果断A掉了...It's time to bet RP. 题意:给一个多边形,然后放进去两个圆,让两个圆的覆盖面积尽量最大,输出两个圆心的坐标. 思路:将多边形的边向里 ...
- POJ 3384 放地毯【半平面交】
<题目链接> 题目大意: 给出一个凸多边形的房间,根据风水要求,把两个圆形地毯铺在房间里,不能折叠,不能切割,可以重叠.问最多能覆盖多大空间,输出两个地毯的圆心坐标.多组解输出其中一个,题 ...
- POJ 3384 Feng Shui (半平面交)
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 3743 Accepted: 1150 Speci ...
随机推荐
- supervisord
[简介] supervisord的官网:http://supervisord.org.看懂英文的可以不用看我的博客,直接看文档就行了,文档写得非常好.点个赞!! Supervisor是一个客户/服务器 ...
- Android:控件WebView显示网页
WebView可以使得网页轻松的内嵌到app里,还可以直接跟js相互调用. webview有两个方法:setWebChromeClient 和 setWebClient setWebClient:主要 ...
- hdu5785(极角排序求所有锐角钝角个数)
做法很显然,求出所有的锐角和钝角就能求出有多少个锐角三角形了. 我用了愚钝的方法,写了两三个小时... 看了下别人简单的代码.学习了下做法. sort(temp+,temp+cnt+);//排序 Fo ...
- ltib学习抄录
linux -- LTIB学习笔记 一 安装篇二 运行篇三 修改工具包 四 编译新的内核 ---------相关资料------------------------------------------ ...
- python操作mongodb之五大量写操作
import pymongo #库名 db = pymongo.MongoClient('192.168.30.252',27017).bulk_example #test集合插入 db.test.i ...
- java 基础(第一天)
1. 一个文件里面只能有一个 public 修饰的方法 且方法名与文件名保持一致. 如: public class main(){ } class car(){ } class dog(){ } ...
- centos7 使用 omnibus包安装方式,安装 gitlab7.4
centos7 使用 omnibus包安装方式,安装 gitlab7.4 1: gitlab是一个开源的软件,类似于github.com那样的git代码管理仓库: 官网 https://about.g ...
- 【bzoj3625】【xsy1729】小朋友和二叉树
[bzoj3625]小朋友与二叉树 题意 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有 ...
- Bootstrap标签
Bootstrap是Twitter推出的一个用于前端开发的开源工具包.用外链加载的方式可以将Bootstrap链接进来 常用方式: <link rel="stylesheet" ...
- canvas调节视频颜色
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...