3680: 吊打XXX
3680: 吊打XXX
思路:
模拟退火。
代码:
跑的特别慢。。。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<cctype> 5 #include<cmath> 6 7 using namespace std; 8 9 const int N = 10010; 10 struct Node{ 11 double x,y,w; 12 }d[N],ans; 13 int n; 14 double minans = 1e18; 15 16 double dis(Node a,Node b) { 17 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 18 } 19 double check(Node p) { 20 double ret = 0; 21 for (int i=1; i<=n; ++i) 22 ret += d[i].w*dis(p,d[i]); 23 if (ret < minans) 24 ans = p,minans = ret; 25 return ret; 26 } 27 double Rand() { 28 return rand()%1000/1000.0; 29 } 30 void SA() { 31 double T = 100000; 32 Node now = ans; 33 while (T > 0.001) { 34 Node nxt; 35 nxt.x = now.x+T*(Rand()*2.0-1.0); 36 nxt.y = now.y+T*(Rand()*2.0-1.0); 37 double Delta = check(now)-check(nxt); 38 if (Delta > 0 || exp(Delta/T)>Rand()) now = nxt; 39 T *= 0.993; 40 } 41 for (int i=1; i<=1000; ++i) { 42 Node nxt; 43 nxt.x = ans.x+T*(Rand()*2.0-1.0); 44 nxt.y = ans.y+T*(Rand()*2.0-1.0); 45 check(nxt); 46 } 47 } 48 int main() { 49 srand(19970815); 50 scanf("%d",&n); 51 ans.x = ans.y = 0; 52 for (int i=1; i<=n; ++i) { 53 scanf("%lf%lf%lf",&d[i].x,&d[i].y,&d[i].w); 54 ans.x += d[i].x; 55 ans.y += d[i].y; 56 } 57 ans.x /= (double)n; 58 ans.y /= (double)n; 59 SA(); 60 printf("%.3lf %.3lf",ans.x,ans.y); 61 return 0; 62 }