CodeForces 710B Optimal Point on a Line
递推。
先对$a[i]$进行从小到大排序。
然后计算出每个点左边所有点到这个点的距离之和$L[i]$,以及右边每个点到这个点的距离之和$R[i]$。
这两个都可以递推得到。
$L\left[ i \right] = L\left[ {i - 1} \right] + \left( {i - 1} \right)×(a\left[ i \right] - a[i - 1])$,
$R\left[ i \right] = R\left[ {i + 1} \right] + \left( {n-i} \right)×(a\left[ i+1 \right] - a[i])$。
然后寻找到$L[i]+R[i]$最小的位置,最后输出那个位置即可。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi=acos(-1.0),eps=1e-8; const int maxn=3e5+10; LL a[maxn],L[maxn],R[maxn],Min; int n; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); sort(a+1,a+1+n); for(int i=1;i<=n;i++) L[i]=L[i-1]+(i-1)*(a[i]-a[i-1]); for(int i=n;i>=1;i--) R[i]=R[i+1]+(n-i)*(a[i+1]-a[i]); Min=1; for(int i=2;i<=n;i++) if(L[i]+R[i]<L[Min]+R[Min]) Min=i; printf("%lld\n",a[Min]); return 0; }