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 }