POJ 1379 Run Away 【基础模拟退火】

亦凉 2021-12-10 16:39 312阅读 0赞

题意:找出一点,距离所有所有点的最短距离最大

二维平面内模拟退火即可,同样这题用最小圆覆盖也是可以的。

Source Code:

  1. //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
  2. #include <stdio.h>
  3. #include <iostream>
  4. #include <fstream>
  5. #include <cstring>
  6. #include <cmath>
  7. #include <stack>
  8. #include <string>
  9. #include <map>
  10. #include <queue>
  11. #include <vector>
  12. #include <ctime>
  13. #include <algorithm>
  14. #define LL long long
  15. #define Max(a,b) (((a) > (b)) ? (a) : (b))
  16. #define Min(a,b) (((a) < (b)) ? (a) : (b))
  17. #define Abs(x) (((x) > 0) ? (x) : (-(x)))
  18. #define MOD 1000000007
  19. #define eps 1e-8
  20. #define pi acos(-1.0)
  21. using namespace std;
  22. const int inf = 0x3f3f3f3f;
  23. const int N = 15;
  24. const int L = 35;
  25. int t,n;
  26. double X ,Y, best[50];
  27. struct Point{
  28. double x,y;
  29. bool check(){
  30. if(x > -eps && x < eps + X && y > -eps && y < eps + Y)
  31. return true;
  32. return false;
  33. }
  34. }p[1005],tp[50];
  35. double dist(Point p1,Point p2){
  36. return sqrt((p1.x-p2.x) * (p1.x-p2.x) + (p1.y-p2.y) * (p1.y-p2.y));
  37. }
  38. double min_dis(Point p0){
  39. double ans = inf;//
  40. for(int i = 0; i < n; ++i)
  41. ans = min(ans,dist(p[i],p0));//
  42. return ans;
  43. }
  44. Point rand_point(double x, double y){
  45. Point c;
  46. c.x = (rand() % 1000 + 1) / 1000.0 * x;
  47. c.y = (rand() % 1000 + 1) / 1000.0 * y;
  48. return c;
  49. }
  50. int main(){
  51. srand(time(NULL));
  52. scanf("%d",&t);
  53. while(t--){
  54. scanf("%lf%lf%d",&X,&Y,&n);
  55. for(int i = 0; i < n; ++i)
  56. scanf("%lf%lf",&p[i].x,&p[i].y);
  57. for(int i = 0; i < N; ++i){
  58. tp[i] = rand_point(X, Y);
  59. best[i] = min_dis(tp[i]);
  60. }
  61. double step = max(X,Y) / sqrt(1.0 * n);
  62. while(step > 1e-3){
  63. for(int i = 0; i < N; ++i){
  64. Point cur;
  65. Point pre = tp[i];
  66. for(int j = 0; j < L; ++j){
  67. double angle = (rand() % 1000 + 1) / 1000.0 * 2 * pi;
  68. cur.x = pre.x + cos(angle) * step;
  69. cur.y = pre.y + sin(angle) * step;
  70. if(!cur.check()) continue;
  71. double tmp = min_dis(cur);
  72. if(tmp > best[i]){
  73. //
  74. tp[i] = cur;
  75. best[i] = tmp;
  76. }
  77. }
  78. }
  79. step *= 0.85;
  80. }
  81. int idx = 0;
  82. for(int i = 0; i < N; ++i){
  83. if(best[i] > best[idx]){
  84. //
  85. idx = i;
  86. }
  87. }
  88. printf("The safest point is (%.1f, %.1f).\n",tp[idx].x,tp[idx].y);
  89. //printf("%.1f\n",best[idx]);
  90. }
  91. return 0;
  92. }

转载于:https://www.cnblogs.com/wushuaiyi/p/4242426.html

发表评论

表情:
评论列表 (有 0 条评论,312人围观)

还没有评论,来说两句吧...

相关阅读

    相关 模拟退火

    Summary 退火总结.退火其实不难...难的是怎么调参. 贡献两页提交才只有\\(55pts\\)的经历真是惨不忍睹.这就是调参的艰难. 主要就是这么几个参数

    相关 模拟退火算法(代码)

    在实际日常中,人们会经常遇到如下问题:在某个给定的定义域![X][]内,求函数![f(x)][f_x]对应的最优值。此处以最小值问题举例(最大值问题可以等价转化成最小值问题),