洛谷P2333 [SCOI2006]一孔之见
辣鸡题目毁我人生败我前程
50分代码
//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
#define pi acos(-1)
#define eps 1e-9
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
const int N=107;
typedef long long LL;
typedef double db;
using namespace std;
int n,cnt[N];
db S;
template<typename T>void read(T &x) {
char ch=getchar(); x=0; T f=1;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct pt {
db x,y;
pt(){}
pt(db x,db y):x(x),y(y){}
}p[N],jd[N][2];
struct Line {
pt a,b;
Line(){}
Line(pt a,pt b):a(a),b(b){}
}L[N];
int dcmp(db x) { return fabs(x)<=eps?0:(x>0?1:-1);}
bool operator == (const pt&A,const pt&B) { return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0; }
bool operator < (const pt&A,const pt&B) { return dcmp(A.x-B.x)<0||(dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)<0); }
pt operator * (const pt&A,const db&B) { return pt(B*A.x,B*A.y); }
pt operator / (const pt&A,const db&B) { return pt(A.x/B,A.y/B); }
pt operator + (const pt&A,const pt&B) { return pt(A.x+B.x,A.y+B.y); }
pt operator - (const pt&A,const pt&B) { return pt(A.x-B.x,A.y-B.y); }
db cross(pt A,pt B) { return A.x*B.y-A.y*B.x; }
db dot(pt A,pt B) { return A.x*B.x+A.y*B.y; }
db length(pt A) { return dot(A,A); }
db pf(db x) { return x*x; }
int ck(pt A,Line li) {
return dcmp(sqrt(length(A-li.a))+sqrt(length(A-li.b))-sqrt(length(li.a-li.b)))==0;
}
void get_jd(int id,Line li,db r) {
cnt[id]=0;
db a=li.a.x,b=li.a.y,c=li.b.x,d=li.b.y;
db e=pf(c-a)+pf(d-b),f=2.0*a*(c-a)+2.0*b*(d-b),g=a*a+b*b-r*r;
db dt=f*f-4*e*g;
if(dcmp(dt)<0) return;
if(dcmp(dt)==0) cnt[id]=1;
else cnt[id]=2;
db t1=(-f+sqrt(dt))/e/2.0;
db t2=(-f-sqrt(dt))/e/2.0;
jd[id][0]=pt(a+t1*(c-a),b+t1*(d-b));
jd[id][1]=pt(a+t2*(c-a),b+t2*(d-b));
if(cnt[id]==2)
if(!ck(jd[id][1],li)) cnt[id]--;
if(!ck(jd[id][0],li)) {
cnt[id]--;
if(cnt[id]) jd[id][0]=jd[id][1];
}
}
int ck(db r) {
db rs=0;
int jds=0,f=0;
For(i,1,n) {
get_jd(i,L[i],r);
jds+=cnt[i];
if(cnt[i]==2) f=1;
}
if(jds==2&&!f) {
For(i,1,n) {
int pr=i==1?n:i-1;
if(cnt[i]==1&&cnt[pr]==1) {
pt A=jd[i][0],B=jd[pr][0],C=p[i];
db a=length(B-C),b=length(A-C),c=length(A-B);
rs=r*r*acos((a+b-c)/(2.0*sqrt(a)*sqrt(b)));
rs+=fabs(cross(A,C));
rs+=fabs(cross(B,C));
break;
}
}
return dcmp(rs-S*2.0)>=0;
}
db sum=2.0*pi;
For(i,1,n) {
if(cnt[i]==2) {
pt A=jd[i][0],B=jd[i][1];
rs+=fabs(cross(A,B));
db a=length(B),b=length(A),c=length(A-B);
sum-=acos((a+b-c)/(2.0*sqrt(a)*sqrt(b)));
}
}
rs+=r*r*sum;
return dcmp(rs-S*2.0)>=0;
}
int main() {
#ifdef DEBUG
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
read(n); scanf("%lf",&S);
For(i,1,n)
scanf("%lf%lf",&p[i].x,&p[i].y);
p[n+1]=p[1];
For(i,1,n) L[i]=Line(p[i],p[i+1]);
db l=0,r=1e20;
while(fabs(r-l)>eps) {
db mid=((l+r)/2.0);
if(ck(mid)) r=mid;
else l=mid;
}
printf("%.2lf\n",l);
return 0;
}