题意:
有四个点,在每个点画一个圆,互相不能重叠,求最大的半径和。
题解:
可知任意两条边的和有一个上限。必定至少有两条边的和等于上限,所以先枚举是哪两条边,如a和b,并且设a的值为x,则c和d的值也可得(c=min(len_ac-a,len_bc-len_ab+x),是一条折线)。那么a+b+c+d的值由x确定,由于函数由一些线段组成,所以根据x的取值区间可以得到最大值。
要注意的是:
1、某些ab和是不可能达到上限的。
2、c+d的值也不能超出限制。
//Time:0ms
//Memory:188KB
//Length:3078B
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#define EPS 1e-6
#define PI 3.1415926535898
#define INF 1000000000
#define MAXN 1010
#define MP(x,y) (make_pair((x),(y)))
#define FI first
#define SE second
using namespace std;
struct _line
{
double x,c,a,b;
};
_line line[2][2],nline[8];
int xx[4],yy[4],top;
double len[4][4],l,r;
void addline(int h1,int h2,double x,double c,double a,double b)
{
line[h1][h2].x=x,line[h1][h2].c=c;
line[h1][h2].a=a,line[h1][h2].b=b;
if(line[h1][h2].a>line[h1][h2].b)
swap(line[h1][h2].a,line[h1][h2].b);
line[h1][h2].a=max(line[h1][h2].a,l);
line[h1][h2].b=min(line[h1][h2].b,r);
}
double cal(int a,int b)
{
return sqrt(1.0*(xx[a]-xx[b])*(xx[a]-xx[b])+1.0*(yy[a]-yy[b])*(yy[a]-yy[b]));
}
void lineadd(int h11,int h12,int h21,int h22)
{
_line tmpline;
tmpline.x=line[h11][h12].x+line[h21][h22].x;
tmpline.c=line[h11][h12].c+line[h21][h22].c;
tmpline.a=max(line[h11][h12].a,line[h21][h22].a);
tmpline.b=min(line[h11][h12].b,line[h21][h22].b);
nline[top++]=tmpline;
}
double calans(int h,double a,double b)
{
a=max(a,nline[h].a),b=min(b,nline[h].b);
if(nline[h].a>nline[h].b-EPS) return 0.0;
if(a>b-EPS) return 0.0;
return max((a*nline[h].x+nline[h].c),(b*nline[h].x+nline[h].c));
}
int main()
{
//freopen("J:\\MyDocument\\Code\\input.txt","r",stdin);
double ans,tmpans;
while(scanf("%d%d",&xx[0],&yy[0])==2)
{
ans=-1e100;
for(int i=1;i<4;++i)
scanf("%d%d",&xx[i],&yy[i]);
for(int i=0;i<4;++i)
for(int j=i+1;j<4;++j)
len[i][j]=len[j][i]=cal(i,j);
for(int i=0;i<4;++i)
for(int j=i+1;j<4;++j)
{
int a=i,b=j,c=-1,d=-1;
for(int k=0;k<4;++k)
if(k!=i&&k!=j)
{
if(c==-1) c=k;
else d=k;
}
l=max(EPS,max(len[a][b]-len[b][c],len[a][b]-len[b][d]));
r=min(len[a][b],min(len[a][c],len[a][d]));
if(l>r-EPS||r<EPS) continue;
addline(0,0,-1,len[a][c],len[a][c]+EPS,(len[a][c]+len[a][b]-len[b][c])*0.5);
addline(0,1,1,len[b][c]-len[a][b],len[a][b]-len[b][c]+EPS,(len[a][c]+len[a][b]-len[b][c])*0.5);
addline(1,0,-1,len[a][d],len[a][d]+EPS,(len[a][d]+len[a][b]-len[b][d])*0.5);
addline(1,1,1,len[b][d]-len[a][b],len[a][b]-len[b][d]+EPS,(len[a][d]+len[a][b]-len[b][d])*0.5);
top=0;
tmpans=-1e100;
for(int k=0;k<2;++k)
lineadd(0,k,1,0),lineadd(0,k,1,1);
for(int k=0;k<top;++k)
tmpans=max(calans(k,l,r),tmpans);
ans=max(ans,len[a][b]+min(tmpans,len[c][d]));
}
printf("%.8f\n",abs(ans));
}
return 0;
}