hdu3932 最小圆覆盖-模拟退火实现-3+
2011-08-24 10:39
253 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3932
题意:给一堆点,求一个点到这些点的最远距离最小。。。精度0.1即可
分析:
此题本来是最小圆覆盖的模板题。。。我一开始就想到费马点的模拟退火去了。。花了一个下午没写出来。。。。
最开始是用4个方向的搜索判断减小步长的方式,后来改到8个方向还是不行,精度都调到10e-9都不行。。。最后改成对当前点周围很多点(貌似用了60个)进行判断精度只需要到0.1就过了。。。表示本人无法解释原因。。。
以后不敢写模拟退火了。。上次福州现场赛调了那么久的精度险过啊。。。。。有木有!!!!!
代码:
题意:给一堆点,求一个点到这些点的最远距离最小。。。精度0.1即可
分析:
此题本来是最小圆覆盖的模板题。。。我一开始就想到费马点的模拟退火去了。。花了一个下午没写出来。。。。
最开始是用4个方向的搜索判断减小步长的方式,后来改到8个方向还是不行,精度都调到10e-9都不行。。。最后改成对当前点周围很多点(貌似用了60个)进行判断精度只需要到0.1就过了。。。表示本人无法解释原因。。。
以后不敢写模拟退火了。。上次福州现场赛调了那么久的精度险过啊。。。。。有木有!!!!!
代码:
#include<iostream> #include<cmath> using namespace std; const double pi = 3.141592654; const int N=1010; struct point { double x, y; } p , mn, mx, mid, mid1; int n, X, Y; double ans, ans1; double dis(point a, point b) { return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } void cal(double x, double y) { int i, j; double mx=0, tmp; point tp; tp.x = x; tp.y = y; for(i=0; i<n; i++) { tmp = dis(p[i], tp); if(tmp>mx) mx = tmp; } if(ans1>mx) { ans1 = mx; mid1 = tp; } } int main() { int i, j, k; double width; while(scanf("%d%d%d", &X, &Y, &n)!=EOF) { mn.x = mn.y = 0x7fffffff; mx.x = mx.y = 0; for(i=0; i<n; i++) { scanf("%lf%lf", &p[i].x, &p[i].y); if(p[i].x<mn.x) mn.x = p[i].x; if(p[i].y<mn.y) mn.y = p[i].y; if(p[i].x>mx.x) mx.x = p[i].x; if(p[i].y>mx.y) mx.y = p[i].y; } mid.x = (mn.x+mx.x)/2; mid.y = (mn.y+mx.y)/2; mid1 = mid; width = mx.x; if(mx.y>width) width = mx.y; ans1 = 0; for(i=0; i<n; i++) { if(dis(mid, p[i])>ans1) ans1 = dis(mid, p[i]); } ans = ans1; double ii; while(1) { /* cal(mid.x-width, mid.y); //判断4个,8个方向不行。。即使精度调到10e-9 cal(mid.x+width, mid.y); cal(mid.x, mid.y-width); cal(mid.x, mid.y+width); cal(mid.x-width, mid.y-width); cal(mid.x-width, mid.y+width); cal(mid.x+width, mid.y-width); cal(mid.x+width, mid.y+width); */ for(ii=0; ii<=2*pi; ii+=0.1) //旋转对很多个点进行判断。。 { cal(mid.x+width*cos(ii), mid.y+width*sin(ii)); } if(ans-ans1<0.1 && width<0.001) break; if(ans1<ans) { ans = ans1; mid = mid1; } else width *= 0.5; } printf("(%.1lf,%.1lf).\n", mid.x, mid.y); printf("%.1lf\n", sqrt(ans)); } return 0; }
相关文章推荐
- HDU 4766 模拟退火(最小圆覆盖) + 二分
- POJ2069 最小球体覆盖, 模拟退火
- HDU 3007 Buried memory(点集最小圆覆盖 模拟退火解法)
- poj2069Super Star【空间最小球覆盖模拟退火】
- POJ 最小球覆盖 模拟退火
- ZOJ1450 BZOJ1136 BZOJ1137 HDU3932[最小圆覆盖]
- bzoj1336/1337 && hdu3932 最小圆覆盖 计算几何:随机增量法&模拟退火
- 【高级算法】遗传,模拟退火,禁忌,Lasvegas等算法详解与实现
- div模拟textarea以css控制最大高度和最小高度实现高度自适应实例页面
- poj-1548-Robots- 贪心+模拟 / 最小路径覆盖
- 用两个栈实现队列、旋转数组的最小数、斐波那契数列、青蛙跳台阶、矩形覆盖 --漫漫算法路 刷题篇
- 模拟退火 hdu3932
- POJ 2069 Super Star(模拟退火,最小球覆盖)
- POJ 1422 二分匹配 最小路径覆盖(邻接表实现)
- 最小覆盖圆模版 hdu3932 + 模拟退火
- 智能算法---模拟退火搜索函数最小值
- poj 3041 Asteroids(二分图 *【矩阵实现】【最小点覆盖==最大匹配数】)
- Graph的算法实现: 寻找一幅图的最小生成树(MST)
- 使用" 参数化基类" 和" 成员函数指针" 模拟实现虚函数--在实际中的应用
- OS作业调度中HRN的模拟实现