POJ--1379(模拟退火)

2015-04-17 23:45:14

题意:给出一个框内的n个点(地雷),让你求出一个到所有点距离最小值最大的位置。

  随即1k个点来找,步长为max(X,Y),缩小系数为0.5 .. (事实上这些值都没有硬性要求)

  然后就是直接上模拟退火,注意步长最小值要设为一个比较小的数已保证精度(比如10^-3)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <map>
 7 #include <set>
 8 #include <climits>
 9 #include <stack>
10 #include <queue>
11 #include <ctime>
12 #include <string>
13 #include <iostream>
14 #include <algorithm>
15 using namespace std;
16 
17 #define MEM(a,b) memset(a,b,sizeof(a))
18 #define REP(i,n) for(int i=0;i<(n);++i)
19 #define FOR(i,a,b) for(int i=(a);i<=(b);++i)
20 #define getmid(l,r) ((l) + ((r) - (l)) / 2)
21 #define MP(a,b) make_pair(a,b)
22 
23 typedef long long ll;
24 typedef pair<int,int> pii;
25 const int INF = (1 << 30) - 1;
26 const int MAXN = 1010;
27 const double cof = 0.5;
28 const double eps = 1e-3;
29 const double deta = 0.7;
30 
31 int T,N,M,K;
32 double X[MAXN],Y[MAXN];
33 int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
34 
35 double Dis(double a1,double b1,double a2,double b2){
36     return sqrt((a1-a2)*(a1-a2) + (b1-b2)*(b1-b2));
37 }
38 
39 double Cal(double a,double b){
40     double res = Dis(a,b,X[0],Y[0]);
41     FOR(i,1,K - 1) res = min(res,Dis(a,b,X[i],Y[i]));
42     return res;
43 }
44 
45 int main(){
46     srand((unsigned)time(NULL));
47     int a,b;
48     scanf("%d",&T);
49     FOR(tt,1,T){
50         scanf("%d%d%d",&N,&M,&K);
51         REP(i,K) scanf("%lf%lf",&X[i],&Y[i]);
52         double ans = -1,ansx,ansy;
53         REP(o,1000){
54             double sx = rand() % (N + 1);
55             double sy = rand() % (M + 1);
56             double res = Cal(sx,sy);
57             double step = max(N,M);
58             while(step > eps){
59                 while(1){
60                     bool mov = false;
61                     REP(k,4){
62                         double tx = sx + dir[k][0] * step;
63                         double ty = sy + dir[k][1] * step;
64                         if(tx < 0 || tx > N || ty < 0 || ty > M) continue;
65                         double tmp = Cal(tx,ty);
66                         if(tmp > res || (double)rand()/INT_MAX > deta){
67                             res = tmp;
68                             sx = tx;
69                             sy = ty;
70                             mov = true;
71                         }
72                     }
73                     if(mov == false) break;
74                 }
75                 step *= cof;
76             }
77             if(ans == -1 || res > ans){
78                 ans = res;
79                 ansx = sx;
80                 ansy = sy;
81             }
82         }
83         printf("The safest point is (%.1f, %.1f).\n",ansx,ansy);
84     }
85     return 0;
86 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/4436403.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值