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 }