[hdu4311]Meeting point-1

题意:在整数坐标轴上找一个距离所有给定点距离最小的点。

解题关键:对x和y分别处理,前缀和预处理所有点到最小点的距离,每点的$sum$等于左边的贡献+右边的贡献,最后取$min$即可。

复杂度:$O(nlogn)$

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<cmath>
 7 using namespace std;
 8 typedef long long ll;
 9 const ll INF = 1ll<<61-1;
10 struct node{
11     ll x,y,sum;
12 }p[100002];
13 bool cmp1(const node &a,const node &b){
14     return a.x<b.x;
15 }
16 
17 bool cmp2(const node &a,const node &b){
18     return a.y<b.y;
19 }
20 ll dis[100002];
21 ll sum1[100002];
22 int main(){
23     ll t;
24     scanf("%I64d",&t);
25     while(t--){
26         memset(p,0,sizeof p);
27         ll n;
28         scanf("%I64d",&n);
29         for(int i=1;i<=n;i++)   scanf("%I64d%I64d",&p[i].x,&p[i].y);
30         sort(p+1,p+n+1,cmp1);
31         for(int i=1;i<=n;i++) dis[i]=p[i].x-p[1].x;
32         for(int i = 1;i <= n;i++) sum1[i]=sum1[i-1]+dis[i];
33         for(int i=1;i<=n;i++){
34             p[i].sum+=abs((i-1)*dis[i]-sum1[i-1]);
35             p[i].sum+=abs((sum1[n]-sum1[i])-dis[i]*(n-i));
36         }
37         sort(p+1,p+n+1,cmp2);
38         for(int i=1;i<=n;i++) dis[i]=p[i].y-p[1].y;
39         for(int i = 1;i <= n;i++) sum1[i]=sum1[i-1]+dis[i];
40         for(int i=1;i<=n;i++){
41             p[i].sum+=abs((i-1)*dis[i]-sum1[i-1]);
42             p[i].sum+=abs((sum1[n]-sum1[i])-dis[i]*(n-i));
43         }
44         ll ma=INF;
45         for(int i=1;i<=n;i++){
46             if(p[i].sum<ma){
47                 ma=p[i].sum;
48             }
49         }
50         printf("%lld\n",ma);
51     }
52     
53 }

 

posted @ 2017-10-10 03:04  Elpsywk  阅读(183)  评论(0编辑  收藏  举报