Language:
Feng Shui
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 nlines contain two integers xi and yi each — coordinates of the i-th corner (−1000 ≤ xi, yi ≤ 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 x1, y1, x2, y2 to the output file, where (x1, y1) and (x2, y2) 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
Sample Output
Hint |
题意:给出两个圆的半径将两个圆放在多边形内求能占的最大面积可以重叠但不可以越过边界求两圆的圆心所在的位置;
解题思路:用半平面交将多边形每个边向内推进R然后枚举各个点之间最大距离即为两圆的圆心坐标
注意只有一组测试案例;
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#define eps 1e-10
using namespace std;
struct point{
double x,y;
}A[110],p[110],q[110];
int N,R,endcnt,tempcnt;
void guizheng(){
point temp;
for(int i=1;i<(N+1)/2;++i){
temp=A[i];
A[i]=A[N-i];
A[N-i]=temp;
}
}
void init(){
for(int i=1;i<=N;++i)
p[i]=A[i];
p[N+1]=p[1];p[0]=p[N];
endcnt=N;
}
double MAX(double a,double b){
return a>b?a:b;
}
double dist(point p1,point p2){
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
void getline(point p1,point p2,double &a,double &b,double &c){
a=p2.y-p1.y;
b=p1.x-p2.x;
c=p2.x*p1.y-p2.y*p1.x;
}
point getinter(point p1,point p2,double a,double b,double c){
double u=fabs(a*p1.x+b*p1.y+c);
double v=fabs(a*p2.x+b*p2.y+c);
point temp;
temp.x=(v*p1.x+u*p2.x)/(u+v);
temp.y=(v*p1.y+u*p2.y)/(u+v);
return temp;
}
void cut(double a,double b,double c){
tempcnt=0;
for(int i=1;i<=endcnt;++i){
if(a*p[i].x+b*p[i].y+c>=0)q[++tempcnt]=p[i];
else{
if(a*p[i-1].x+b*p[i-1].y+c>0){
q[++tempcnt]=getinter(p[i],p[i-1],a,b,c);
}
if(a*p[i+1].x+b*p[i+1].y+c>0){
q[++tempcnt]=getinter(p[i],p[i+1],a,b,c);
}
}
}
for(int i=1;i<=tempcnt;++i){
p[i]=q[i];
}
p[tempcnt+1]=p[1];p[0]=p[tempcnt];
endcnt=tempcnt;
}
void solve(){
//guizheng();
A[N+1]=A[1];
init();
for(int i=1;i<=N;++i){
point ta,tb,tc;
tc.x=A[i+1].y-A[i].y;
tc.y=A[i].x-A[i+1].x;
double k=R*1.0/sqrt(tc.x*tc.x+tc.y*tc.y);
tc.x*=k;tc.y*=k;
ta.x=A[i].x+tc.x;ta.y=A[i].y+tc.y;
tb.x=A[i+1].x+tc.x;tb.y=A[i+1].y+tc.y;
double a,b,c;
getline(ta,tb,a,b,c);
cut(a,b,c);
}
double max=-1;
int r1,r2;
for(int i=1;i<=endcnt;++i){
for(int j=i+1;j<=endcnt;++j){
double temp=dist(p[i],p[j]);
if(temp>max){
max=temp;
r1=i;r2=j;
}
}
}
printf("%.6lf %.6lf %.6lf %.6lf\n",p[r1].x,p[r1].y,p[r2].x,p[r2].y);
}
int main()
{
int i,j,k,l;
scanf("%d%d",&N,&R);
for(i=1;i<=N;++i){
scanf("%lf%lf",&A[i].x,&A[i].y);
}
solve();
return 0;
}