HDU 3932 模拟退火

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 }

 

你可能感兴趣的:(HDU)