poj 3384 Feng Shui (半平面交)

原创 2017年01月03日 19:42:42

Feng Shui
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 5519   Accepted: 1656   Special Judge

Description

Feng shui is the ancient Chinese practice of placement and arrangement of space to achieve harmony with the environment. George has recently got interested in it, and now wants to apply it to his home and bring harmony to it.

There is a practice which says that bare floor is bad for living area since spiritual energy drains through it, so George purchased two similar round-shaped carpets (feng shui says that straight lines and sharp corners must be avoided). Unfortunately, he is unable to cover the floor entirely since the room has shape of a convex polygon. But he still wants to minimize the uncovered area by selecting the best placing for his carpets, and asks you to help.

You need to place two carpets in the room so that the total area covered by both carpets is maximal possible. The carpets may overlap, but they may not be cut or folded (including cutting or folding along the floor border) — feng shui tells to avoid straight lines.

Input

The first line of the input file contains two integer numbers n and r — the number of corners in George’s room (3 ≤ n ≤ 100) and the radius of the carpets (1 ≤ r ≤ 1000, both carpets have the same radius). The following n lines contain two integers xi and yi each — coordinates of the i-th corner (−1000 ≤ xiyi ≤ 1000). Coordinates of all corners are different, and adjacent walls of the room are not collinear. The corners are listed in clockwise order.

Output

Write four numbers x1y1x2y2 to the output file, where (x1y1) and (x2y2) denote the spots where carpet centers should be placed. Coordinates must be precise up to 4 digits after the decimal point.

If there are multiple optimal placements available, return any of them. The input data guarantees that at least one solution exists.

Sample Input

#15 2 -2 0 -5 3 0 8 7 3 5 0
#24 3 0 0 0 8 10 8 10 0

Sample Output

#1-2 3 3 2.5
#23 5 7 3

Hint

Source

Northeastern Europe 2006, Northern Subregion

[Submit]   [Go Back]   [Status]   [Discuss]


题目大意:再凸多边形内放两个半径r的圆,求如果放置是覆盖的面积最大。

题解:半平面交。

将边界向内缩R,然后求凸包的最远点对。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1003
#define eps 1e-12
#define inf 1e9
using namespace std;
struct vector {
	double x,y;
	vector (double X=0,double Y=0){
		x=X,y=Y;
	}
}a[N],tmp[N],p[N];
struct data{
	vector a,b;
}line[N];
int n,m;
double r,pi=acos(-1.0);
typedef vector point;
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 t){
	return vector (a.x*t,a.y*t);
}
vector operator /(vector a,double t){
	return vector (a.x/t,a.y/t);
}
int dcmp(double x)
{
	if (fabs(x)<eps) return 0;
	return x<0?-1:1;
}
double cross(vector a,vector b)
{
	return a.x*b.y-a.y*b.x;
}
point rotate(vector a,double rad)
{
	return point(a.x*cos(rad)-a.y*sin(rad),a.y*cos(rad)+a.x*sin(rad));
}
double len(vector a)
{
	return sqrt(a.x*a.x+a.y*a.y);
}
void init()
{
	m=0;
	p[m++]=point(inf,inf);
	p[m++]=point(-inf,inf);
	p[m++]=point(-inf,-inf);
	p[m++]=point(inf,-inf);
}
point glt(point a,point a1,point b,point b1)
{
	vector v=a1-a; vector w=b1-b;
	vector u=a-b;
	double t=cross(w,u)/cross(v,w);
	return a+v*t;
}
void cut(point a,point b)
{
	int cnt=0;
	memset(tmp,0,sizeof(tmp));
	for (int i=0;i<m;i++){
		double c=cross(b-a,p[i]-a);
		double d=cross(b-a,p[(i+1)%m]-a);
		if (dcmp(c)<=0) tmp[cnt++]=p[i];
		if (dcmp(c)*dcmp(d)<0) 
		 tmp[cnt++]=glt(a,b,p[i],p[(i+1)%m]);
	}
	m=cnt;
	for (int i=0;i<cnt;i++) p[i]=tmp[i];
}
int main()
{
	    freopen("a.in","r",stdin);
	    scanf("%d%lf",&n,&r);
		for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
		a[n+1]=a[1];
		for (int i=2;i<=n+1;i++){
			vector v=a[i]-a[i-1];
			vector u=rotate(v,3*pi/2)/len(v);
		    u=u*r;
		    line[i-1].a=a[i-1]+u;
		    line[i-1].b=line[i-1].a+v;
		    //cout<<line[i-1].a.x<<" "<<line[i-1].a.y<<endl;
			//cout<<line[i-1].b.x<<" "<<line[i-1].b.y<<endl;
		}
		init();
		for (int i=1;i<=n;i++) cut(line[i].a,line[i].b);
		point ans,ansx; double mx=0;
		for (int i=0;i<m-1;i++)
		 for (int j=i+1;j<m;j++){
		 	double t=len(p[i]-p[j]);
		 	if (t>mx) {
		 		mx=t;
		 		ans=p[i]; ansx=p[j];
			 }
		 }
		if (m==1) ans=p[0],ansx=p[0];
		printf("%.4lf %.4lf %.4lf %.4lf\n",ans.x,ans.y,ansx.x,ansx.y);
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

【半平面交】 POJ 3384 Feng Shui

先把每条边压缩r

POJ 3384 || Feng Shui (半平面交内推R

题目大意:给你一个凸包,里面放两个半径相同的圆,问你如果让这两个圆覆盖凸包的面积最大。 两个圆可以覆盖重合,但不是不会跑到墙角折起来。输出放置圆的两个圆的圆心坐标。如果有多种可能,输出任意一种。 ...
  • FXXKI
  • FXXKI
  • 2015年05月17日 17:26
  • 424

Poj 3384 Feng Shui (半平面求交应用)

题目链接 http://poj.org/problem?id=3384 题意:两个圆半径均为r(可重合但不能超出多边形边界)覆盖一个多边形,覆盖的面积最大时求两点坐标。 思路:若多边形足够大,则随...

poj 3384 Feng Shui(内推进半平面交+最远点对)

Feng Shui Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3964   Acce...

POJ3384Feng Shui【半平面交】

Language: Default Feng Shui Time Limit: 2000MS   Memory Limit: 65536K Total Subm...

poj3384 Feng Shui 半平面交

//题目链接:http://poj.org/problem?id=3384 //题意:用两个圆去覆盖一个多边形,求最多覆盖面积时两个圆的圆心(按一定顺序)。 //多边形向内推进r求半平面交 + 最...
  • ssslpk
  • ssslpk
  • 2012年07月28日 00:15
  • 859

POJ 3384 Feng Shui(半平面交)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove 题目:给出一个凸多边形的房...

POJ 3384 Feng Shui 风水 (半平面交求可以放入的两个相同圆的最大面积)

将两个半径为 r 的圆放入一个多边形中,两圆可以重叠,问两个圆占据最大面积时圆心坐标是多少。...

POJ 3384 Feng Shui 半平面交

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

poj 3384 Feng Shui - 多边形的边内退一段距离后求半平面交,然后求最远点对

/* poj 3384 Feng Shui - 多边形的边内退一段距离后求半平面交,然后求最远点对 */ #include #include #include using names...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj 3384 Feng Shui (半平面交)
举报原因:
原因补充:

(最多只允许输入30个字)