Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 5631 | Accepted: 1728 |
Description
Input
Output
Sample Input
3 1000 50 1 10 10 100 100 4 10 10 10 90 90 10 90 90 3000 3000 4 1200 85 63 2500 2700 2650 2990 100
Sample Output
The safest point is (1000.0, 50.0). The safest point is (50.0, 50.0). The safest point is (1433.0, 1669.8).
在给定范围内找一个点,距离所有点的最小值最大,
做过类似题目,但是发现以前的方法行不通了,看别人的写法,先找20个随机种子,然后逐步更新,最后取最优解。学习了。
代码:
/* *********************************************** Author :_rabbit Created Time :2014/5/11 21:41:17 File Name :3.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; 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){ 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) { 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<=20;j++) for (int k=1;k<=20;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<=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); 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; }
原文地址:http://blog.csdn.net/xianxingwuguan1/article/details/25564299