HDU3932
题目大意:给定一堆点,找到一个点的位置使这个点到所有点中的最大距离最小
简单的模拟退火即可
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <ctime> 7 #include <algorithm> 8 9 using namespace std; 10 11 #define N 1005 12 #define PI acos(-1.0) 13 #define random(x) (rand()%x+1) 14 const int P = 20; 15 const int L = 25; 16 double X,Y; 17 int n; 18 double mindis[N]; 19 20 struct Point{ 21 double x , y; 22 Point(double x=0 , double y=0):x(x),y(y){} 23 void input(){ 24 scanf("%lf%lf" , &x , &y); 25 } 26 }p[N] , tmp[N]; 27 28 double dis(Point a , Point b) 29 { 30 double x = a.x-b.x , y=a.y-b.y; 31 return sqrt(x*x+y*y); 32 } 33 34 double cal(Point a) 35 { 36 double maxn = 0; 37 for(int i=0 ; i<n ; i++) maxn = max(maxn , dis(a , p[i])); 38 return maxn; 39 } 40 41 int main() 42 { 43 #ifndef ONLINE_JUDGE 44 freopen("a.in" , "r" , stdin); 45 #endif // ONLINE_JUDGE 46 while(~scanf("%lf%lf%d" , &X , &Y , &n)) 47 { 48 for(int i=0 ; i<n ; i++) p[i].input(); 49 for(int i=0 ; i<P ; i++){ 50 tmp[i].x = random(1000)/1000.0*X; 51 tmp[i].y = random(1000)/1000.0*Y; 52 mindis[i] = cal(tmp[i]); 53 } 54 double step = sqrt(X*X+Y*Y)/2; 55 while(step>1e-3){ 56 for(int i=0 ; i<P ; i++){ 57 for(int j=0 ; j<L ; j++){ 58 Point cur; 59 double ang = random(1000)/1000.0*2*PI; 60 cur.x = tmp[i].x+cos(ang)*step; 61 cur.y = tmp[i].y+sin(ang)*step; 62 if(cur.x<0 || cur.x>X || cur.y<0 || cur.y>Y) continue; 63 double val = cal(cur); 64 if(val<mindis[i]){ 65 mindis[i] = val; 66 tmp[i] = cur; 67 } 68 } 69 } 70 step *= 0.85; 71 } 72 double ret = 1e20; 73 Point u; 74 for(int i=0 ; i<P ; i++){ 75 if(mindis[i]<ret){ 76 u = tmp[i]; 77 ret = mindis[i]; 78 } 79 } 80 printf("(%.1f,%.1f).\n%.1f\n" , u.x,u.y,ret); 81 } 82 return 0; 83 }
时间: 2024-10-07 12:40:07