您的位置:首页 > Web前端

[USACO5.2.2 Electric Fences]

2012-03-03 18:42 405 查看
[关键字]:随机化

[题目大意]:有一些平行与坐标轴的线段,找一个点到各线段距离和最小。

//==================================================================================================

[分析]:先找一个起始点(左下)然后确定一个范围,在这个范围内找到最优值,然后以最优值坐标为起点缩小范围重复,直到范围小于要求的精度。

[代码]:

View Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int MAXN=200;

struct node
{
int x,y;
}a[MAXN],b[MAXN];
int N;

void Init()
{
scanf("%d",&N);
for (int i=1;i<=N;i++)
scanf("%d%d%d%d",&a[i].x,&a[i].y,&b[i].x,&b[i].y);
}

double Find(double x,double y)
{
double temp=0;
for (int i=1;i<=N;i++)
{
if (a[i].x==b[i].x && abs(a[i].y-y)+abs(b[i].y-y)==abs(a[i].y-b[i].y)) {temp+=abs(a[i].x-x);continue;}
if (a[i].y==b[i].y && abs(a[i].x-x)+abs(b[i].x-x)==abs(a[i].x-b[i].x)) {temp+=abs(a[i].y-y);continue;}
temp+=min(sqrt((a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y)),sqrt((b[i].x-x)*(b[i].x-x)+(b[i].y-y)*(b[i].y-y)));
}
return temp;
}

void Solve()
{
double minx=50,miny=50,size=50;
double Min=1e10;
do{
double x=minx-size,y=miny-size;
size/=20;
for (int i=1;i<=40;i++)
{
x+=size;
for (int i=1;i<=40;i++)
{
y+=size;
double p=Find(x,y);
if (p<Min)
{
Min=p;
minx=x;
miny=y;
}
}
y-=size*40;
}
}while (size>0.1);
printf("%.1lf %.1lf %.1lf",minx,miny,Min);
}

int main()
{
Init();
Solve();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: