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 ...
随机推荐
- Android自动接听&挂断电话(包含怎么应对4.1以上版本的权限检
一 前言 这两天要研究类似白名单黑名单以及手势自动接听的一些功能,所以呢,自然而然的涉及到怎么自动接听/挂断电话的功能了.对于自动接听这一块,android4.1版本及其以上的版本和之前的版本处理逻 ...
- Java 获取各时区时间,获取当前时间到格林威治时间1970年01月01日00时00分00秒的秒数
格林威治时间即UTC/GMT时间,1970年01月01日00时00分00秒(即UTC+8的北京时间1970年01月01日08时00分00秒)计算代码如下: /** * 获取指定时间到格林威治时间的秒数 ...
- HTML5地理位置概述和地理位置对象的详解
一.地理位置 经度 : 南北极的连接线 纬度 : 东西连接的线 二.位置信息从何而来 IP地址 GPS全球定位系统 Wi-Fi无线网络 基站 三.地理位置对象(navi ...
- python字符串替换的2种有效方法
python 字符串替换可以用2种方法实现:1是用字符串本身的方法.2用正则来替换字符串 下面用个例子来实验下:a = 'hello word'我把a字符串里的word替换为python1用字符串本身 ...
- LF CRLF
在git提交的时候 有时候会提示这个 LF will be replaced by CRLF 这是因为window的结束符是:回车和换行 crlfmac和linux的结束符是 lf, 于是当代码在这两 ...
- BOM头的来源
类似WINDOWS自带的记事本等软件,在保存一个以UTF-8编码的文件时,会在文件开始的地方插入三个不可见的字符(0xEF 0xBB 0xBF,即BOM).它是一串隐藏的字符,用于让记事本等编辑器识别 ...
- VC++编译libpng
目录 第1章简介 1 第2章 Visual C++6.0 2 2.1 打开项目 2 2.2 编译宏 3 2.2.1 小结 5 第3章 Visual C++2010 ...
- unity3d模型制作规范
1. 单位,比例统一 在建模型前先设置好单位,在同一场景中会用到的模型的单位设置必须一样,模型与模型之间的比例要正确,和程序的导入单位一致,即便到程序需要缩放也可以统一调整缩放比例.统一单位为米. 2 ...
- DSP28377S - ADC学习编程笔记
DSP28377S - ADC学习编程笔记 彭会锋 2016-08-04 20:19:52 1 ADC类型导致的配置区别 F28377S的ADC类型是Type 4类型,我的理解是不同类型的ADC采 ...
- 《javascript高级程序设计》 第24章 最佳实践 Best Practices
24.1 可维护性 Maintainability24.1.1 什么是可维护的代码 What Is Maintainable Code?24.1.2 代码约定 Code Conventions 24. ...