【BZOJ3680】吊打XXX 计算几何 广义费马点+模拟退火(爬山算法)

做题之前:

令一个点到一个分身的距离为两点间的几何距离*这个分身的重力,则到所有分身的距离之和最小的点即为所求。

因此题各种参数实在太恐怖,使得模拟退火TLE/WA无数次。强烈建议此题更名为“吊打出题人”。

在此感谢网上的大神给了我们调参数的伟大参考!!!

吊打XXX C++代码实现:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 10010
using namespace std;
int n,x[N],y[N],w[N];double dis,ansx,ansy,xx,yy;
double dist(double x1,double x2,double y1,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%d%d%d",&x[i],&y[i],&w[i]);
	double t=1000;
	for(int i=1;i<=n;i++)
		ansx+=x[i]*w[i],ansy+=y[i]*w[i];
	ansx/=n,ansy/=n;
	while(t>0.000000001)
	{
		xx=yy=0;
		for(int i=1;i<=n;i++)
			dis=dist(ansx,x[i],ansy,y[i]),
			xx+=(x[i]-ansx)*w[i]/dis,
			yy+=(y[i]-ansy)*w[i]/dis;
		ansx+=xx*t,ansy+=yy*t;
		t=t>0.5?t*0.5:t*0.98;
	}
	printf("%.3lf %.3lf\n",ansx,ansy);
	return 0;
}
点赞