Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

统计

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\n",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\n",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\n",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).\n",tp[ansi].x,tp[ansi].y);
93         printf("%.1lf\n",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

posted on   Pentium.Labs  阅读(452)  评论(0编辑  收藏  举报

编辑推荐:
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
阅读排行:
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率
· AI Agent爆火后,MCP协议为什么如此重要!



Pentium.Lab Since 1998

点击右上角即可分享
微信分享提示