当前位置: 代码迷 >> 综合 >> 【 POJ - 2420 】A Star not a Tree?(模拟退火、三分套三分)
  详细解决方案

【 POJ - 2420 】A Star not a Tree?(模拟退火、三分套三分)

热度:7   发布时间:2023-12-06 19:35:47.0

给出平面上N<=100)个点,你需要找到一个这样的点,使得这个点到N个点的距离之和尽可能小。输出这个最小的距离和(四舍五入到最近的整数)。

Input

第一行N,接下来N行每行两个整数,表示N个点

Output

一行一个正整数,最小的距离和。

Sample Input

4
0 0
0 10000
10000 10000
10000 0

Sample Output

28284

 

思路:

模拟退火,注意四舍五入,用double 输出需要用%f,longlong输出需要round()。

三分套三分,确定x后,y是一个二次函数,可以用三分套三分求解。

模拟退火:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const double eps=1e-10;
int n;
struct node{int x,y;void input(){scanf("%d%d",&x,&y);}
}a[maxn];
double dis(double x,double y,double x1,double y1){return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
}
double alldis(double x,double y){double res=0;for(int i=0;i<n;i++){res+=dis(x,y,a[i].x,a[i].y);}return res;
}
double solve(double x,double y){double T=100000;while(T>eps){double tx=x+(rand()*2-RAND_MAX)*T;double ty=y+(rand()*2-RAND_MAX)*T;double delta=alldis(tx,ty)-alldis(x,y);if(delta<0){x=tx;y=ty;}else if(exp(-delta/T)*RAND_MAX>rand()){x=tx;y=ty;}T*=0.99;}return alldis(x,y);
}
int main(){cin>>n;for(int i=0;i<n;i++) a[i].input();printf("%.0f\n",solve(0,0));return 0;
}

三分套三分:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<bitset>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const double eps=1e-10;
int n;
struct node{int x,y;void input(){scanf("%d%d",&x,&y);}
}a[maxn];
double dis(double x,double y,double x1,double y1){return sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
}
double alldis(double x,double y){double res=0;for(int i=0;i<n;i++){res+=dis(x,y,a[i].x,a[i].y);}return res;
}double check(double x){double l=0,r=10000;double ans=0;while((r-l)>eps){double m1=l+(r-l)/3;double m2=r-(r-l)/3;double ans1=alldis(x,m1);double ans2=alldis(x,m2);if(ans1<ans2) r=m2,ans=ans1;else l=m1,ans=ans2;}return ans;
}
int main(){cin>>n;for(int i=0;i<n;i++) a[i].input();double l=0,r=10000;double ans=0;while((r-l)>eps){double m1=l+(r-l)/3;double m2=r-(r-l)/3;double ans1=check(m1);double ans2=check(m2);if(ans1<ans2) r=m2,ans=ans1;else l=m1,ans=ans2;}printf("%.0f\n",ans);return 0;
}

 

  相关解决方案