• [洛谷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;
    }
    

      

  • 相关阅读:
    Esper学习之六:EPL语法(二)
    从排序开始(五) 堆排序
    hdu 4750 Count The Pairs (2013南京网络赛)
    并查集+二分-hdu-4750-Count The Pairs
    VS2010+ICE3.5运行官方demo报错----std::bad_alloc
    ServiceStack.Redis.IRedisHash.cs
    ServiceStack.Data.IEntityStore.cs
    ServiceStack.Caching.ICacheClientExtended.cs
    ServiceStack.Caching.ICachClient.cs
    ServiceStack.Caching.IRemoveByPattern.cs
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10054140.html
Copyright © 2020-2023  润新知