萌新刚学模拟退火,求调参
查看原帖
萌新刚学模拟退火,求调参
247359
WuhenGSL楼主2021/7/13 11:25

RT,交了4页了,最高一次70pt

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 1010
#define re register
#define rd T*(rand()*2-RAND_MAX)
#define LB double
using namespace std;
const long double D=0.994,eps=1e-12;
int n,m,R,times=50;
LB x[N],y[N],r[N],p[N],q[N];
inline LB dis(LB x,LB y,LB X,LB Y)
{
	return sqrt((x-X)*(x-X)+(y-Y)*(y-Y));
}
inline int calc(LB x0,LB y0)
{
	LB d=R;
	int res=0;
	for(re int i=1;i<=n;++i)
		d=min(d,dis(x0,y0,x[i],y[i])-r[i]);
	for(re int i=1;i<=m;++i)
		if(dis(x0,y0,p[i],q[i])<=d)res++;
	return res;
}
int main()
{
	LB x0,y0,x1,y1,best,ans,res,T,bx=0,by=0;
	scanf("%d%d%d",&n,&m,&R);
	for(re int i=1;i<=n;++i)
	{
		scanf("%lf%lf%lf",&x[i],&y[i],&r[i]);
	}
	for(re int i=1;i<=m;++i)
	{
		scanf("%lf%lf",&p[i],&q[i]);
		bx+=p[i],by+=q[i];
	}
	best=ans=calc(bx/=m,by/=m);
	srand(time(0));
	while((double)clock()/CLOCKS_PER_SEC<=0.996)
	//while(times--)
	{
		ans=best,x0=bx,y0=by;
		for(T=3605;T>eps;T*=D)
		{
			x1=x0+rd,y1=y0+rd;
			res=calc(x1,y1);
			if(best<res)
				best=res,bx=x1,by=y1;
			if(exp(ans-res/T)<(LB)rand()/RAND_MAX)
				ans=res,x0=x1,y0=y1;
		}
	}
	printf("%.0lf",best);
	return 0;
}
2021/7/13 11:25
加载中...