POJ 1379 (随机算法)模拟退火

 题目大意:

给定一堆点,找到一个点的位置使这个点到所有点中的最小距离最大

这里数据范围很小,精度要求也不高,我们这里可以利用模拟退火的方法,随机找到下一个点,如果下一个点比当前点优秀就更新当前点

参考:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

http://wenku.baidu.com/view/0c6b5df5f61fb7360b4c65a9.html

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <climits>
 6 #include <cmath>
 7 #include <queue>
 8 #include <cstdlib>
 9 #include <ctime>
10 using namespace std;
11 #define random(x) ((rand()%x)+1)
12 #define N 1005
13 #define ll long long
14 #define eps 1e-4
15 const double PI = acos(-1.0);
16 const int INF = INT_MAX;
17 const int P = 20;
18 const int L = 30;
19 
20 double x,y;
21 int n;
22 double dist[N];
23 
24 struct Point{
25     double x,y;
26     Point(double x=0 , double y=0):x(x),y(y){}
27 }p[N] , tmp[N];
28 
29 double dis(Point a , Point b)
30 {
31     double x = a.x-b.x , y = a.y - b.y;
32     return sqrt(x*x+y*y);
33 }
34 
35 double min_dis(Point t)
36 {
37     double minn = 1e20;
38     for(int i=0 ; i<n ; i++) minn=min(minn , dis(t , p[i]));
39     return minn;
40 }
41 
42 bool ok(Point t)
43 {
44     return t.x>=0 && t.x<=x && t.y>=0 && t.y<=y;
45 }
46 
47 int main()
48 {
49     #ifndef ONLINE_JUDGE
50         freopen("a.in" , "r" , stdin);
51     #endif // ONLINE_JUDGE
52     srand(time(0));
53     int T;
54     scanf("%d" , &T);
55     while(T--)
56     {
57         Point ans;
58         double ret=0;
59 
60         scanf("%lf%lf%d" , &x , &y , &n);
61         for(int i=0 ; i<n ; i++){
62             scanf("%lf%lf" , &p[i].x , &p[i].y);
63         }
64 
65         for(int i=0 ; i<P ; i++){
66             tmp[i].x = random(1000)/1000.0*x;
67             tmp[i].y = random(1000)/1000.0*y;
68             dist[i] = min_dis(tmp[i]);
69         }
70         double step = sqrt(x*x+y*y)/2;
71         while(step>eps){
72 
73             for(int i=0 ; i<P ; i++){
74                 Point cur;
75                 for(int j=0 ; j<L ; j++){
76                     double ang = random(1000)/1000.0*2*PI;
77                     cur.x = tmp[i].x+cos(ang)*step;
78                     cur.y = tmp[i].y+sin(ang)*step;
79                     if(!ok(cur)) continue;
80                     double val = min_dis(cur);
81                     if(val>dist[i]){
82                         tmp[i]=cur;
83                         dist[i] = val;
84                     }
85                 }
86             }
87             step *= 0.85;
88         }
89 
90         for(int i=0 ; i<P ; i++){
91             if(dist[i]>ret){
92                 ret = dist[i];
93                 ans = tmp[i];
94             }
95         }
96         printf("The safest point is (%.1f, %.1f).
" , ans.x , ans.y);
97     }
98     return 0;
99 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4530499.html