记录编号 422623 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [Ural 1520] 帝国反击战 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 3.653 s
提交时间 2017-07-10 08:09:24 内存使用 2.58 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<climits>
using namespace std;
typedef long double db;
const int N=1e5+10;
const db pi=acos(-1.0);
db sqr(db x){return x*x;}
int n,r;
struct pt{
	db x,y;
	pt(db X=0,db Y=0){x=X;y=Y;}
	pt operator - (const pt a)const{return pt(x-a.x,y-a.y);}
	db len(){return sqr(x)+sqr(y);}
}p[N],ansp;
db ans;
db distance(pt x){
	db Min=1e9;
	for (int i=1;i<=n;i++) Min=min(Min,(p[i]-x).len());
	if (Min>ans) ans=Min,ansp=x;
	return Min;
}
const db step=pi/40;
void solve(pt now){//爬山法
	if (clock()>650000) return;
	db R=r*0.1;//当前步长
	db C=0.93;//缩减速度
	db eps=1e-10;//精度
	db now_val=distance(now);
	int cnt=381;
	for (;R>eps;R*=C){
		//printf("(%.5Lf,%.5Lf)\n",now.x,now.y);
		pt last=now;
		for (db alpha=0;alpha<pi*2;alpha+=step){
			pt next(last.x+R*sin(alpha),last.y+R*cos(alpha));
			if (next.len()>r*r+2e-5) continue;
			db next_val=distance(next);
			if (next_val>now_val) now_val=next_val,now=next;
		}
		cnt--;
		if (cnt*R+sqrt(now_val)<sqrt(ans)) return;
	}
}
int rand(int n){return rand()%n+1;}
db _rand(){return 1.0*rand()/INT_MAX;}
int main()
{
	//freopen("a.txt","r",stdin);
	freopen("empirestrikesback.in","r",stdin);
	freopen("empirestrikesback.out","w",stdout);
	srand(time(0));
	scanf("%d%d",&n,&r);
	for (int i=1;i<=n;i++) scanf("%Lf%Lf",&p[i].x,&p[i].y);
	db R,step;
	R=r*1.0/3.0,step=pi/3;
	for (db alpha=0;alpha<pi*2;alpha+=step) solve(pt(R*cos(alpha),R*sin(alpha)));
	R=r*2.0/3.0,step=pi/6;
	for (db alpha=0;alpha<pi*2;alpha+=step) solve(pt(R*cos(alpha),R*sin(alpha)));
	for (int i=1;i<=20;i++){
		db R=_rand()*r,alpha=_rand()*pi*2;
		solve(pt(R*cos(alpha),R*sin(alpha)));
	}
	/*R=r*1.0/4.0,step=pi/6;
	for (db alpha=0;alpha<pi*2;alpha+=step) solve(pt(R*cos(alpha),R*sin(alpha)));
	R=r*2.0/4.0,step=pi/8;
	for (db alpha=0;alpha<pi*2;alpha+=step) solve(pt(R*cos(alpha),R*sin(alpha)));
	R=r*3.0/4.0,step=pi/10;
	for (db alpha=0;alpha<pi*2;alpha+=step) solve(pt(R*cos(alpha),R*sin(alpha)));
	for (int i=1;i<=30;i++){
		db R=_rand()*r,alpha=_rand()*pi*2;
		solve(pt(R*cos(alpha),R*sin(alpha)));
	}*/
	R=5e-6,step=pi/1000;
	for (db alpha=0;alpha<pi*2;alpha+=step){
		pt next(ansp.x+R*cos(alpha),ansp.x+R*sin(alpha));
		if (next.len()>r*r+2e-5) continue;
		distance(next);
	}
	printf("%.10Lf\n",sqrt(ans));
	return 0;
}