zoukankan      html  css  js  c++  java
  • [洛谷P4035][JSOI2008]球形空间产生器

    题目大意:给你$n$个点坐标,要你求出圆心

    题解:随机化,可以随机一个点当圆心,然后和每个点比较,求出平均距离$r$,如果到这个点的距离大于$r$,说明离这个点远了,就给圆心施加一个向这个点的力;若小于$r$,说明近了,就施加一个远离这个点的力。所有点比较完后,把假设的圆心按合力方向移动一个距离,距离和当前温度有关。时间越久,温度越低

    卡点:第$8$个点精度总是不够,拼命调参,调好后第$3$个点就$Tle$了,最后卡时过的

    C++ Code:

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <ctime>
    #define maxn 12
    int n;
    struct Point {
    	double x[maxn], w;
    	inline friend Point operator + (const Point &lhs, const Point &rhs) {
    		Point res;
    		for (register int i = 0; i < n; i++) res.x[i] = lhs.x[i] + rhs.x[i];
    		return res;
    	}
    	inline friend Point operator - (const Point &lhs, const Point &rhs) {
    		Point res;
    		for (register int i = 0; i < n; i++) res.x[i] = lhs.x[i] - rhs.x[i];
    		return res;
    	}
    	inline void operator /= (const int &rhs) {
    		for (register int i = 0; i < n; i++) x[i] /= rhs;
    	}
    } s[maxn], ans;
    
    inline double sqr(double x) {return x * x;}
    inline double abs(const Point &O) {
    	double res = 0;
    	for (int i = 0; i < n; i++) res += sqr(O.x[i]);
    	return sqrt(res);
    }
    inline double dis(Point O) {
    	double res = 0;
    	for (int i = 0; i <= n; i++) res += abs(O - s[i]);
    	return res;
    }
    
    const double ST = 5000, delT = 0.99995, eps = 1e-5;
    const int Tim = 1, __Tim = 250000;
    double V[maxn];
    void SA() {
    	double T = ST;
    	while (T > eps) {
    		double sum = dis(ans) / (n + 1);
    		for (int i = 0; i < n; i++) {
    			V[i] = 0;
    			for (int j = 0; j <= n; j++) {
    				V[i] += (abs(ans - s[j]) - sum) * (s[j].x[i] - ans.x[i]);
    			}
    			V[i] /= n + 1;
    		}
    		for (int i = 0; i < n; i++) {
    			ans.x[i] += T * V[i];
    		}
    		T *= delT;
    	}
    	for (int Tim = 0; Tim < __Tim && 1. * clock() / CLOCKS_PER_SEC < .9; Tim++) {
    		double sum = dis(ans) / (n + 1);
    		for (int i = 0; i < n; i++) {
    			V[i] = 0;
    			for (int j = 0; j <= n; j++) {
    				V[i] += (abs(ans - s[j]) - sum) * (s[j].x[i] - ans.x[i]);
    			}
    			V[i] /= n + 1;
    		}
    		for (int i = 0; i < n; i++) {
    			ans.x[i] += T * V[i];
    		}
    	}
    }
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i <= n; i++) {
    		for (int j = 0; j < n; j++) scanf("%lf", s[i].x + j);
    		ans = ans + s[i];
    	}
    	ans /= n + 1;
    	for (int i = 0; i < Tim; i++) SA();
    	for (int i = 0; i < n; i++) {
    		 printf("%.3lf", ans.x[i]);
    		 putchar(i == n - 1 ? '
    ' : ' ');
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    hdu 1823 Luck and Love 二维线段树
    UVA 12299 RMQ with Shifts 线段树
    HDU 4578 Transformation 线段树
    FZU 2105 Digits Count 线段树
    UVA 1513 Movie collection 树状数组
    UVA 1292 Strategic game 树形DP
    【ACM】hdu_zs2_1003_Problem C_201308031012
    qsort快速排序
    【ACM】nyoj_7_街区最短路径问题_201308051737
    【ACM】nyoj_540_奇怪的排序_201308050951
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10054140.html
Copyright © 2011-2022 走看看