poj 1379 Run Away
2013-02-27 15:28
387 查看
题意就是寻找最安全的点,也就是找到一点使得他在题目给的区域之内与所有点最短距离最大,很容易想到这题可以用不断趋近的模拟退火来做,先随机一部分点集,对每个点分别点的扩展,选取较优点来替代原来的点,然后不断缩小步长,点的扩展时试了几种方法,发现还是使用正余弦比较靠谱。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; struct point { double x,y,dis; }a[2000],b[100],ans; int n,X,Y; double dis(point c) //计算最短距离 { double sum=1e8; for (int i=1;i<=n;++i) if (sum>sqrt((c.x-a[i].x)*(c.x-a[i].x)+(c.y-a[i].y)*(c.y-a[i].y))) sum=sqrt((c.x-a[i].x)*(c.x-a[i].x)+(c.y-a[i].y)*(c.y-a[i].y)); return sum; } void Solve() { for (int i=1;i<=30;++i) //随机点集 { b[i].x=rand()%X+1,b[i].y=rand()%Y+1; b[i].dis=dis(b[i]); } point t; for (double i=max(X,Y);i>=1e-2;i*=0.9) //步长缩短 for (int j=1;j<=30;j++) //固定步长,对每个点进行扩展 for (int k=1;k<=30;k++) //扩展的尝试 { double ran=rand(); t.x=b[j].x+cos(ran)*i; t.y=b[j].y+sin(ran)*i; if (0>t.x || t.x>X || 0>t.y || t.y>Y) continue; t.dis=dis(t); if (t.dis>b[j].dis) b[j]=t; } ans.dis=-1; for (int i=1;i<=30;++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); 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; }
相关文章推荐
- poj1379 run away
- poj1379 Run Away
- poj 1379 Run Away 计算几何 模拟退火
- poj 1379 Run Away
- poj-1379 Run Away(模拟退火算法)
- POJ 1379 Run Away
- POJ 1379 run away 模拟退火算法
- 【模拟退火】poj1379 Run Away
- poj 1379 Run Away
- poj 1379 Run Away(模拟退火)
- poj 1379 Run Away 模拟退火 难度:1
- POJ 1379 Run Away(基础模拟退火)
- 【POJ1379】Run Away 模拟退火
- POJ 1379 Run Away 模拟退火
- POJ 1379 Run Away
- poj 1379 Run Away 随机化变步长贪心
- POJ 1379-Run Away解题报告
- 【模拟退火】 poj1379 Run Away
- poj 1379 Run Away
- POJ 1379 Run Away 【基础模拟退火】