//题目链接:http://poj.org/problem?id=3384
//题意:用两个圆去覆盖一个多边形,求最多覆盖面积时两个圆的圆心(按一定顺序)。
//多边形向内推进r求半平面交 + 最远点对
//这里的数据不够大,可以用暴力求最远点对 94ms AC,代码如下:
#include<iostream>
#include<cstdio>
#include<math.h>
#define eps 1e-8
//using namespace std;
const int MAXN=202;
struct point{double x,y;};
point points[MAXN],p[MAXN],q[MAXN];
int n;
double r;
bool zero(double x)
{
return x>0? x<eps:x>-eps;
}
double xmult(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int same_side(point p1,point p2,point l1,point l2)
{
return xmult(l1,p1,l2)*xmult(l1,p2,l2)>eps;
}
point intersection(point p1,point p2,point p3,point p4)
{
point ret=p1;
double t=((p1.x-p3.x)*(p3.y-p4.y)-(p3.x-p4.x)*(p1.y-p3.y))
/((p1.x-p2.x)*(p3.y-p4.y)-(p3.x-p4.x)*(p1.y-p2.y));
ret.x+=t*(p2.x-p1.x);
ret.y+=t*(p2.y-p1.y);
return ret;
}
void polygon_cut(int &n,point *p,point l1,point l2,point side)
{
point pp[1000];
int m=0,i;
for(i=0;i<n;i++)
{
if(same_side(p[i],side,l1,l2))
pp[m++]=p[i];
if(!same_side(p[i],p[(i+1)%n],l1,l2)
&&!(zero(xmult(p[i],l1,l2))
&&zero(xmult(p[(i+1)%n],l1,l2))))
pp[m++]=intersection(p[i],p[(i+1)%n],l1,l2);
}
n=0;
for(i=0;i<m;i++)
if(!i||!zero(pp[i].x-pp[i-1].x)||!zero(pp[i].y-pp[i-1].y))
p[n++]=pp[i];
if(zero(p[n-1].x-p[0].x)&&zero(p[n-1].y-p[0].y))
n--;//
// if(n<3)n=0;
}
double distance(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
void slove(double dis,int &m)
{
int i;
for(i=0;i<n;i++)p[i]=points[i];
for(i=0;i<n;i++)
{
point side;
point s=points[i],e=points[(i+1)%n];
double xx=s.x-e.x,yy=s.y-e.y;
double dd=sqrt(xx*xx+yy*yy);
s.x+=dis*(-yy)/dd;
s.y+=dis*(xx)/dd;
e.x+=dis*(-yy)/dd;
e.y+=dis*(xx)/dd;
side.x=s.x-yy;
side.y=s.y+xx;
polygon_cut(m,p,s,e,side);
}
}
int main()
{
while(scanf("%d%lf",&n,&r)!=EOF)
{
int i,j;
for(i=0;i<n;i++)
scanf("%lf%lf",&points[i].x,&points[i].y);
int m=n;
slove(r,m);
// for(i=0;i<m;i++)printf("%lf,%lf\n",p[i].x,p[i].y);
double dis=0;
int s=0,e=0;
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
if(i!=j)
{
double temp=distance(p[i],p[j]);
if(temp-dis>eps)
{
dis=temp;
s=i;e=j;
}
}
}
if(p[s].x-p[e].x>eps||zero(p[s].x-p[e].x)&&p[s].y>-p[e].y>eps)
{
point tt=p[s];
p[s]=p[e];
p[e]=tt;
}
printf("%.10lf %.10lf %.10lf %.10lf\n",p[s].x,p[s].y,p[e].x,p[e].y);
}
return 0;
}
分享到:
相关推荐
计算几何半平面交,poj2451 一题是模版题,这里的代码可以作为模版使用,速度比较快
该资源详细的介绍了acm中的半平面交,你可以通过学习这个,加上poj上的习题练习,则完全掌握半平面交,对你搞acm有很大帮助
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
poj分类poj分类poj分类poj分类
北大POJ1159-Palindrome 解题报告+AC代码
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
poj 百练 题目分类 poj 百练 题目分类
POJ1083的代码,POJ1083的代码,POJ1083的代码
POJ1048,加强版的约瑟夫问题 难度中等
北大POJ2002-Squares 解题报告+AC代码
poj 1001答案
poj1379 给予平面内一个点集; 使用模拟退火求出一个点使该点到上述点集内任意一点最短距离最长。
POJ2968代码有用,欢迎下载,POJ代码