模拟退火求助142分
查看原帖
模拟退火求助142分
285617
黑影洞人楼主2022/8/7 11:52
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
#define int long long
#define N 500000 
using namespace std;
const double eps=1e-9,pi=3.14;
struct node{
	double x,y;
	void in(){scanf("%lf%lf",&x,&y);}
	double dis(node a){return (a.x-x)*(a.x-x)+(a.y-y)*(a.y-y);}
	bool operator<(const node &a)const{return x*y<a.x*a.y;}
}a[N];
int n;
double fi,ans=1e15; 
double calc(double xt){
	xt=(xt/180.0)*pi;
	for(int i=1;i<=n;i++){
		double x=a[i].x,y=a[i].y;
		a[i].x=x*cos(xt)-y*sin(xt);
		a[i].y=x*sin(xt)+y*cos(xt);
	}
	double res=1e15;
	sort(a+1,a+n+1);
	for(int i=1;i<n;i++){
		for(int j=i+1;j<=min(i+5ll,n);j++){
			res=min(res,a[i].dis(a[j]));
		}
	}
	return res;
}
void sa(){
	//printf("%lf\n",fi);
	for(double t=1145;t>eps;t*=0.996){
		double lz=fmod(fi+rand()*t,360.0);
		double now=calc(lz),del=now-ans;
		if(del<0)ans=now,fi=lz;
		else if((-del/t)*RAND_MAX>rand())fi=lz;
		if((double)clock()/CLOCKS_PER_SEC<=0.3){printf("%.0lf\n",ans);exit(0);}
	}
}
signed main(){
	srand(time(0));
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)a[i].in();
	fi=0;
	ans=min(ans,calc(rand()%360));
	sa();
	printf("%.0lf\n",ans);
	return 0;
}


2022/8/7 11:52
加载中...