• hdu3932 模拟退火


    模拟退火绝对是从OI--ACM以来接触过的所有算法里面最黑科技的orz

    题意:地上有一堆hole,要找一个点,使得(距离该点最远的hole的距离)最小。

    sol:本来想套昨天的模拟退火模板,初值(0,0),向8个方向扩散。

    然而这题并没有这么naive。

    模板2.0 get:

     1 #define eps 1e-3
     2 #define pi  acos(-1.0)
     3 #define POI 15            //独立跑POI次,找其中最小的        tp[1..POI]是随机的初值
     4 #define RUN 40            //迭代次数,本题中即点(tx,ty)向RUN个方向发散
     5 
     6 
     7 void sa()
     8 {
     9     for(int i=1;i<=POI;i++)
    10     {
    11         tp[i].x=(rand()%1000+1)/1000.0*X;
    12         tp[i].y=(rand()%1000+1)/1000.0*Y;
    13         sol[i]=dis(tp[i].x,tp[i].y);
    14         //printf("%.1f~%.1f=%.1f
    ",tp[i].x,tp[i].y,sol[i]);
    15     }
    16 
    17     double step=1.0*max(X,Y)/sqrt(1.0*N);
    18     while(step>eps)
    19     {
    20         for(int i=1;i<=POI;i++)
    21         {
    22             double kx=tp[i].x,ky=tp[i].y;
    23             double tx=kx,ty=ky;
    24             for(int j=0;j<RUN;j++)
    25             {
    26                 double angle=(rand()%1000+1)/1000.0*10*pi;
    27                 kx=tx+cos(angle)*step;
    28                 ky=ty+sin(angle)*step;
    29                 if((kx>X)||(ky>Y)||(kx<0)||(ky<0))    continue;
    30                 double tmp=dis(kx,ky);
    31                 if(tmp<sol[i])
    32                 {
    33                     tp[i].x=kx;    tp[i].y=ky;
    34                     sol[i]=tmp;
    35                 }
    36             }
    37         }
    38         step*=0.80;
    39     }
    40 }

    AC Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<ctime>
     5 using namespace std;
     6 
     7 #define eps 1e-3
     8 #define pi  acos(-1.0)
     9 #define POI 15            //独立跑POI次,找其中最小的        tp[1..POI]是随机的初值
    10 #define RUN 40            //迭代次数,本题中即点(tx,ty)向RUN个方向发散
    11 int X,Y,N;
    12 double ans;
    13 int ansi;
    14 struct
    15 {
    16     double x,y;
    17 }tp[1010],hol[1010];
    18 double sol[1010];
    19 
    20 double dist(double x1,double y1,double x2,double y2)
    21 {
    22     return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
    23 }
    24 
    25 double dis(double x,double y)
    26 {
    27     double tmp=0.000;
    28     for(int i=1;i<=N;i++)
    29     {
    30         double tx=hol[i].x,ty=hol[i].y;
    31         tmp=max(tmp,dist(tx,ty,x,y));
    32     }
    33     return tmp;
    34 }
    35 
    36 void sa()
    37 {
    38     for(int i=1;i<=POI;i++)
    39     {
    40         tp[i].x=(rand()%1000+1)/1000.0*X;
    41         tp[i].y=(rand()%1000+1)/1000.0*Y;
    42         sol[i]=dis(tp[i].x,tp[i].y);
    43         //printf("%.1f~%.1f=%.1f
    ",tp[i].x,tp[i].y,sol[i]);
    44     }
    45 
    46     double step=1.0*max(X,Y)/sqrt(1.0*N);
    47     while(step>eps)
    48     {
    49         for(int i=1;i<=POI;i++)
    50         {
    51             double kx=tp[i].x,ky=tp[i].y;
    52             double tx=kx,ty=ky;
    53             for(int j=0;j<RUN;j++)
    54             {
    55                 double angle=(rand()%1000+1)/1000.0*10*pi;
    56                 kx=tx+cos(angle)*step;
    57                 ky=ty+sin(angle)*step;
    58                 if((kx>X)||(ky>Y)||(kx<0)||(ky<0))    continue;
    59                 double tmp=dis(kx,ky);
    60                 if(tmp<sol[i])
    61                 {
    62                     tp[i].x=kx;    tp[i].y=ky;
    63                     sol[i]=tmp;
    64                 }
    65             }
    66         }
    67         step*=0.80;
    68     }
    69 }
    70 
    71 
    72 int main()
    73 {
    74     srand(time(NULL));
    75     while(cin>>X>>Y>>N)
    76     {
    77         for(int i=1;i<=N;i++)
    78             cin>>hol[i].x>>hol[i].y;
    79 
    80         sa();
    81 
    82         ans=(X*X+Y*Y)*100.0;    
    83         for(int i=1;i<=POI;i++)
    84         {
    85             //printf("AA: %.1f~%.1f=%.1f
    ",tp[i].x,tp[i].y,sol[i]);
    86             if(sol[i]<ans)
    87             {
    88                 ans=sol[i];
    89                 ansi=i;
    90             }
    91         }
    92         printf("(%.1f,%.1f).
    ",tp[ansi].x,tp[ansi].y);
    93         printf("%.1lf
    ",ans);
    94     }
    95     return 0;
    96 }
    View Code

    ref:

    http://blog.csdn.net/acm_cxlove/article/details/7954321

    http://blog.csdn.net/zxy_snow/article/details/6682926

    http://www.kuangbin.net/archives/hdu3932#more-435

  • 相关阅读:
    hdu 4476 Cut the rope (2-pointer && simulation)
    hdu 1286 找新朋友 (容斥原理 || 欧拉函数)
    函数存储的另一种思路
    grunt 入门 应用grunt对代码进行压缩
    sublime flatLand 主题
    如何应用r.js对requirejs下的js代码合并
    如何在requirejs下引用bootstrap
    学习在requirejs下如何使用underscore.js模板
    应用js函数柯里化currying 与ajax 局部刷新dom
    js 函数arguments一种用法
  • 原文地址:https://www.cnblogs.com/pdev/p/4539270.html
Copyright © 2020-2023  润新知