标签:des style class blog code http
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 3435 | Accepted: 1724 |
Description
Input
Output
Sample Input
4 0 0 0 10000 10000 10000 10000 0
Sample Output
28284
Source
题目大意:
求n边形的费马点,即找到一个点使得这个点到n个点的距离之和最小。
解题思路:
三角形也有费马点,三角形费马点是这样定义的:寻找三角形内的一个点,使得三个顶点到该点的距离之和最小。
三角形费马点的做法是:
(1)若有一个角大于120度,那么这个角所在的点就是费马点。
(2)若不存在,那么对于三角形ABC,任取两条边(假设AB、AC),向外做等边三角形得到C‘ 和 A‘ ,那么AA‘ 和CC‘ 的交点就是费马点。
那么对于这题n多边形,我采取的策略完全不同,采用了模拟退火的做法,这种做法相对比较简单,也可以用在求三角形费马点之中。
模拟退火算法就跟数值算法里面的自适应算法相同的道理
(1)定义好步长
(2)寻找一个起点,往8个方向的按这个步长搜索。
(3)如果找到比答案更小的点,那么以这个新的点为起点,重复(2)
(4)如果找不到比答案更小的点,那么步长减半,再尝试(2)
(5)直到步长小于要求的答案的精度就停止。
解题代码:
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
const int offx[]={1,1,0,-1,-1,-1,0,1};
const int offy[]={0,1,1,1,0,-1,-1,-1};
const int maxn=110;
const double eps=1e-2;
struct point{
double x,y;
point(double x0=0,double y0=0){x=x0;y=y0;}
double getdis(point p){
return sqrt( (x-p.x)*(x-p.x)+(y-p.y)*(y-p.y) );
}
}p[maxn];
int n;
double getsum(point p0){
double sum=0;
for(int i=0;i<n;i++) sum+=p0.getdis(p[i]);
return sum;
}
void solve(){
for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
double ans=getsum(p[0]),step=100;
point s=p[0],d;
while(step>eps){
bool flag=false;
for(int i=0;i<8;i++){
d=point(s.x+step*offx[i],s.y+step*offy[i]);
double tmp=getsum(d);
if(tmp<ans){
s=d;
ans=tmp;
flag=true;
}
}
if(!flag) step/=2;
}
printf("%.0f\n",ans);
}
int main(){
while(scanf("%d",&n)!=EOF){
solve();
}
return 0;
}
POJ 2420 A Star not a Tree? (计算几何-费马点),布布扣,bubuko.com
POJ 2420 A Star not a Tree? (计算几何-费马点)
标签:des style class blog code http
原文地址:http://blog.csdn.net/a1061747415/article/details/33296795