| 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