POJ 3384 Feng Shui
http://poj.org/problem?id=3384
题意:给一个凸包,求往里面放两个圆(可重叠)的最大面积时的两个圆心坐标。
思路:先把凸包边往内推R,做半平面交,然后做旋转卡壳,此时得到最大距离的点对,就是圆心坐标。
PS:最大长度的初始值要设置为负数,因为距离有可能退化到0,就像这组数据
4 1
0 0
2 0
2 2
0 2
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
const double Pi=acos(-);
double R;
int n,tot;
struct Point{
double x,y;
Point(){}
Point(double x0,double y0):x(x0),y(y0){}
}p[];
struct Line{
Point s,e;
double slop;
Line(){}
Line(Point s0,Point e0):s(s0),e(e0){}
}L[],l[],c[];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>''){if (ch=='-')f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
Point operator /(Point p1,double x){
return Point(p1.x/x,p1.y/x);
}
Point operator *(Point p,double x){
return Point(p.x*x,p.y*x);
}
double operator *(Point p1,Point p2){
return p1.x*p2.y-p1.y*p2.x;
}
Point operator -(Point p1,Point p2){
return Point(p1.x-p2.x,p1.y-p2.y);
}
Point operator +(Point p1,Point p2){
return Point(p1.x+p2.x,p1.y+p2.y);
}
bool cmp(Line p1,Line p2){
if (p1.slop!=p2.slop) return p1.slop<p2.slop;
else return (p1.e-p1.s)*(p2.e-p1.s)<=;
}
Point inter(Line p1,Line p2){
double k1=(p2.e-p1.s)*(p1.e-p1.s);
double k2=(p1.e-p1.s)*(p2.s-p1.s);
double t=(k2)/(k1+k2);
double x=p2.s.x+(p2.e.x-p2.s.x)*t;
double y=p2.s.y+(p2.e.y-p2.s.y)*t;
return Point(x,y);
}
bool jud(Line p1,Line p2,Line p3){
Point p=inter(p1,p2);
return (p-p3.s)*(p3.e-p3.s)>;
}
void phi(){
std::sort(l+,l++tot,cmp);
int cnt=;
for (int i=;i<=tot;i++)
if (l[i].slop!=l[i-].slop)
l[++cnt]=l[i];
int L=,R=;c[L]=l[];c[R]=l[];
for (int i=;i<=cnt;i++){
while (L<R&&jud(c[R],c[R-],l[i])) R--;
while (L<R&&jud(c[L],c[L+],l[i])) L++;
c[++R]=l[i];
}
while (L<R&&jud(c[R],c[R-],c[L])) R--;
while (L<R&&jud(c[L],c[L+],c[R])) L++;
tot=;
c[R+]=c[L];
for (int i=L;i<=R;i++)
p[++tot]=inter(c[i],c[i+]);
}
double sqr(double x){
return x*x;
}
double dis(Point p){
return sqrt(sqr(p.x)+sqr(p.y));
}
Point turn(Point p,double ang){
double Cos=cos(ang),Sin=sin(ang);
double x=Cos*p.x-Sin*p.y;
double y=Cos*p.y+Sin*p.x;
return Point(x,y);
}
Point e(Point p){
double len=dis(p);p=p/len;return p;
}
double dis(Point p1,Point p2){
return dis(p1-p2);
}
void rc(){
p[tot+]=p[];
int k=;
double mx=-;
Point ans1,ans2;
for (int i=;i<=tot;i++){
while (fabs((p[i%tot+]-p[i])*(p[k]-p[i]))<fabs((p[i%tot+]-p[i])*(p[k%tot+]-p[i]))) k=(k)%tot+;
if (mx<dis(p[i],p[k])){
mx=dis(p[i],p[k]);
ans1=p[i];
ans2=p[k];
}
}
printf("%.4f %.4f %.4f %.4f",ans1.x,ans1.y,ans2.x,ans2.y);
}
int main(){
n=read(),R=read();
for (int i=;i<=n;i++) p[i].x=read(),p[i].y=read();
for (int i=;i<=n/;i++) std::swap(p[i],p[n-i+]);
p[n+]=p[];
for (int i=;i<=n;i++)
l[++tot]=Line(p[i],p[i+]),l[tot].slop=atan2(l[tot].e.y-l[tot].s.y,l[tot].e.x-l[tot].s.x);
for (int i=;i<=n;i++){
Point p=e(turn((l[i].e-l[i].s),Pi/2.0))*R;
l[i].s=l[i].s+p;
l[i].e=l[i].e+p;
}
phi();
rc();
}
POJ 3384 Feng Shui的更多相关文章
- poj 3384 Feng Shui (Half Plane Intersection)
3384 -- Feng Shui 构造半平面交,然后求凸包上最远点对. 这题的题意是给出一个凸多边形区域,要求在其中放置两个半径为r的圆(不能超出凸多边形区域),要求求出两个圆心,使得多边形中没有被 ...
- POJ 3384 Feng Shui 半平面交
题目大意:一个人很信"Feng Shui",他要在房间里放两个圆形的地毯. 这两个地毯之间可以重叠,可是不能折叠,也不能伸到房间的外面.求这两个地毯可以覆盖的最大范围.并输出这两个 ...
- POJ 3384 Feng Shui (半平面交)
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 3743 Accepted: 1150 Speci ...
- POJ 3384 Feng Shui(计算几何の半平面交+最远点对)
Description Feng shui is the ancient Chinese practice of placement and arrangement of space to achie ...
- POJ 3384 Feng Shui --直线切平面
题意:房间是一个凸多边形,要在里面铺设两条半径为r的圆形地毯,可以重叠,现在要求分别铺设到哪,使地毯所占的地面面积最大. 解法:要使圆形地毯所占面积最大,圆形地毯一定是与边相切的,这样才能使尽量不重叠 ...
- POJ 3384 Feng Shui(半平面交向内推进求最远点对)
题目链接 题意 : 两个圆能够覆盖的最大多边形面积的时候两个圆圆心的坐标是多少,两个圆必须在多边形内. 思路 : 向内推进r,然后求多边形最远的两个点就是能覆盖的最大面积. #include < ...
- POJ 3384 Feng Shui 凸包直径 + 半平面交
G++一直没有过了 换成 C++果断A掉了...It's time to bet RP. 题意:给一个多边形,然后放进去两个圆,让两个圆的覆盖面积尽量最大,输出两个圆心的坐标. 思路:将多边形的边向里 ...
- poj 3384 半平面交
Feng Shui Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5183 Accepted: 1548 Speci ...
- POJ3384:Feng Shui——题解
http://poj.org/problem?id=3384 题目大意:给一个顺时针序的多边形,求在里面放半径为r的两个圆使得两圆覆盖的面积最大,求出这样的圆的坐标. ———————————————— ...
随机推荐
- Linux 安装字体
把XP下的字体C:\WINDOWS\FONTS\simsun.ttc(也就是宋体,大小为10M),把他重命名为 simsun.ttf 拷贝simsun.ttf 字体到 /usr/share/fonts ...
- 用nginx做代理服务器上网
用nginx做代理服务器上网 目前现状:只有1个机器能上网(web),其他机器不能方法:能上网的做一个代理web服务器中转,其他机器连接它即可.采用nginx Nginx配置如下: server{ ...
- Graphviz-Gdot语言学习
GVEdit这个绘图软件呢我也是刚接触的,感觉画起图来还是很爽的...尤其很熟悉c++后很容易上手这门dot语言. 先看一下十分清新的编程界面: 没有天下最邪恶的语法加亮,没有缩进行...这又算什么! ...
- IIS 403.14 - Forbidden错误解决方法
HTTP 错误 403.14 - ForbiddenWeb 服务器被配置为不列出此目录的内容. 解决方法如下: 打开IIS的”处理程序映射设置“,在右边的操作栏下有 ”添加脚本映射“请求路径:*可执行 ...
- HDOJ 1236 排名(练耐心题)
Problem Description 今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑 每题的分值,所以并不是最后的排名.给定录取分数线,请你写程序找出最后通 ...
- css实现居中的各种方法
css垂直居中有很多种方法,可以参考下这个网站
- HDU-2571命运
Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机 ...
- Swing UI - 可收起与开展内容面板实现演示
基于JAVA Swing实现的自定义组件可折叠的JPanel组件 基本思想: 可折叠面板,分为两个部分-头部面板与内容面板 头部面板– 显示标题,以及对应的icon图标,监听鼠标事件决定内容面板隐藏或 ...
- nutch和solr集成
Linux下的Nutch和solr集成 3.1.Nutch安装 l 解压 tar -zxvf apache-nutch-1.4-bin.tar.gz l 终端下cd到目录 apache-nutch- ...
- CSS 代码是什么?(转)
转自:http://www.divcss5.com/rumen/r95.shtml CSS 代码是什么,什么是CSS代码? 目录 什么是CSS css代码样子(图) 作用 相关扩展阅读 一.了解什么是 ...