USACO 5.2 Electric Fences(模拟退火)

学习模拟退火,讲解看这里:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

代码看的山大一个大神的博客:http://3214668848.blog.163.com/blog/static/48764919200991894621558/

代码里就一个随机数,实现模拟退火算法的代码,比较好懂的。。。

 1 /*

 2  ID: cuizhe

 3  LANG: C++

 4  TASK: fence3

 5 */

 6 #include <iostream>

 7 #include <cstdio>

 8 #include <cstring>

 9 #include <queue>

10 #include <map>

11 #include <ctime>

12 #include <cmath>

13 #include <algorithm>

14 using namespace std;

15 struct node

16 {

17     int x1,y1,x2,y2;

18 }p[151];

19 int a[4] = {0,0,1,-1};

20 int b[4] = {1,-1,0,0};

21 int n;

22 double dis(int x1,int y1,int x2,int y2)

23 {

24     return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));

25 }

26 double Cal(int x,int y)

27 {

28     int i;

29     double ans,temp;

30     ans = 0;

31     for(i = 1;i <= n;i ++)

32     {

33         if(p[i].x1 == p[i].x2&&y >= p[i].y1&&y <= p[i].y2)//点到线段中间的点最短的情况

34         temp = fabs(x-p[i].x1);

35         else if(p[i].y1 == p[i].y2&&x >= p[i].x1&&x <= p[i].x2)//点到线段中间的点最短的情况

36         temp = fabs(y-p[i].y1);

37         else

38         temp = min(dis(x,y,p[i].x1,p[i].y1),dis(x,y,p[i].x2,p[i].y2));//点到线段端点

39         ans += temp;

40     }

41     return ans;

42 }

43 int main()

44 {

45     int i,j,T,num,key,tx,ty,u,x,y;

46     double ans,di;

47     freopen("fence3.in","r",stdin);

48     freopen("fence3.out","w",stdout);

49     scanf("%d",&n);

50     srand(time(NULL));

51 

52     for(i = 1;i <= n;i ++)

53     {

54         scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);

55         if(p[i].x1==p[i].x2 && p[i].y1 > p[i].y2)  swap(p[i].y1, p[i].y2);

56         if(p[i].y1==p[i].y2 && p[i].x1 > p[i].x2)  swap(p[i].x1, p[i].x2);

57         p[i].x1 *= 10;

58         p[i].y1 *= 10;

59         p[i].x2 *= 10;

60         p[i].y2 *= 10;

61     }

62     Cal(0,0);

63     T = 40;

64     num = 200;

65     key = 5;

66     ans = 10000000;

67     x = p[1].x1;

68     y = p[1].y1;

69     while(T--)

70     {

71         for(i = 1;i <= num;i ++)

72         {

73             for(j = 0;j < 4;j ++)

74             {

75                 u = rand()%key;

76                 tx = x + u*a[j]*T;//随机跳跃

77                 ty = y + u*b[j]*T;//随机跳跃

78                 if(tx >= 0&&ty >= 0&&tx <= 1000&&ty <= 1000)

79                 {

80                     di = Cal(tx,ty);

81                     if(ans > di)

82                     {

83                         ans = di;

84                         x = tx;

85                         y = ty;

86                     }

87 

88                 }

89             }

90         }

91     }

92     printf("%.1lf %.1lf %.1lf\n",x/10.0,y/10.0,ans/10.0);

93     return 0;

94 }

 



你可能感兴趣的:(USACO)