zoukankan      html  css  js  c++  java
  • HDU 3932 模拟退火

    HDU3932

     题目大意:给定一堆点,找到一个点的位置使这个点到所有点中的最大距离最小

    简单的模拟退火即可

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <algorithm>
     8 
     9 using namespace std;
    10 
    11 #define N 1005
    12 #define PI acos(-1.0)
    13 #define random(x) (rand()%x+1)
    14 const int P = 20;
    15 const int L = 25;
    16 double X,Y;
    17 int n;
    18 double mindis[N];
    19 
    20 struct Point{
    21     double x , y;
    22     Point(double x=0 , double y=0):x(x),y(y){}
    23     void input(){
    24         scanf("%lf%lf" , &x , &y);
    25     }
    26 }p[N] , tmp[N];
    27 
    28 double dis(Point a , Point b)
    29 {
    30     double x = a.x-b.x , y=a.y-b.y;
    31     return sqrt(x*x+y*y);
    32 }
    33 
    34 double cal(Point a)
    35 {
    36     double maxn = 0;
    37     for(int i=0 ; i<n ; i++) maxn = max(maxn , dis(a , p[i]));
    38     return maxn;
    39 }
    40 
    41 int main()
    42 {
    43     #ifndef ONLINE_JUDGE
    44         freopen("a.in" , "r" , stdin);
    45     #endif // ONLINE_JUDGE
    46     while(~scanf("%lf%lf%d" , &X , &Y , &n))
    47     {
    48         for(int i=0 ; i<n ; i++) p[i].input();
    49         for(int i=0 ; i<P ; i++){
    50             tmp[i].x = random(1000)/1000.0*X;
    51             tmp[i].y = random(1000)/1000.0*Y;
    52             mindis[i] = cal(tmp[i]);
    53         }
    54         double step = sqrt(X*X+Y*Y)/2;
    55         while(step>1e-3){
    56             for(int i=0 ; i<P ; i++){
    57                 for(int j=0 ; j<L ; j++){
    58                     Point cur;
    59                     double ang = random(1000)/1000.0*2*PI;
    60                     cur.x = tmp[i].x+cos(ang)*step;
    61                     cur.y = tmp[i].y+sin(ang)*step;
    62                     if(cur.x<0 || cur.x>X || cur.y<0 || cur.y>Y) continue;
    63                     double val = cal(cur);
    64                     if(val<mindis[i]){
    65                         mindis[i] = val;
    66                         tmp[i] = cur;
    67                     }
    68                 }
    69             }
    70             step *= 0.85;
    71         }
    72         double ret = 1e20;
    73         Point u;
    74         for(int i=0 ; i<P ; i++){
    75             if(mindis[i]<ret){
    76                 u = tmp[i];
    77                 ret = mindis[i];
    78             }
    79         }
    80         printf("(%.1f,%.1f).
    %.1f
    " , u.x,u.y,ret);
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    Floyd算法
    递归函数的学习
    动态联编【转】
    哈希hash
    sizeof与strlen
    写入文件和读取文件信息—Java Card开发第三篇
    文件系统创建—Java Card开发第二篇
    获取缓冲区内容与将缓冲区内容返回—Java card开发第一篇
    i++与++i
    电脑无法登陆ftp
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4530595.html
Copyright © 2011-2022 走看看