1 条题解
-
0
题意:在给定矩阵范围内找一个点,该点距离矩阵内所有点的最小值最大,
在算法书看到这道题,算法为 模拟退火法 在书上看过,又看别人的写法,先找20个随机种子,然后逐步更新,最后取最优解。
具体看代码:
#include <stdio.h> #include <iostream> #include <algorithm> #include<math.h> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0)//3.14 typedef long long ll; struct node { double x,y,dis; } a[2000],b[100],ans; int n,X,Y; double dis(node c) { double sum=1e8; for (int i=1; i<=n; ++i) { double dd=sqrt((c.x-a[i].x)*(c.x-a[i].x)+(c.y-a[i].y)*(c.y-a[i].y)); if(sum>dd)sum=dd;//找到最小距离 } return sum; } void Solve() { for (int i=1; i<=20; ++i)//预20个并行解状态处理 { b[i].x=rand()%X+1,b[i].y=rand()%Y+1;//生成随机位置 b[i].dis=dis(b[i]);//找到位置最小距离 } node t; for (double i=max(X,Y); i>=1e-2; i*=0.9)//初始温度 再温度未退至足够低 退火 for (int j=1; j<=20; j++)//枚举每个状态 for (int k=1; k<=20; k++)//随机调节20个方向 依次迭代 { double ran=rand(); t.x=b[j].x+cos(ran)*i;//取出第j个解状态 t.y=b[j].y+sin(ran)*i;//+随机方向 if (0>t.x || t.x>X || 0>t.y || t.y>Y) continue;//若t在界外 t.dis=dis(t); if (t.dis>b[j].dis) b[j]=t;//更新最大距离状态 } ans.dis=-1; for (int i=1; i<=20; ++i)if (ans.dis<b[i].dis) ans=b[i];//找出最大距离 } int main() { int test; scanf("%d",&test); while (test--) { scanf("%d %d %d",&X,&Y,&n);//矩阵XY for (int i=1; i<=n; i++) scanf("%lf %lf",&a[i].x,&a[i].y);//矩阵内的点 Solve(); printf("The safest point is (%.1f, %.1f).\n",ans.x,ans.y); } return 0; }
- 1
信息
- ID
- 380
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者