【bzoj3170】[Tjoi2013]松鼠聚会(数学题)

  题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3170

  这道题要在n个点中求一个点使其他点到该点的切比雪夫距离最小。

  有个结论:$ (x,y) -> ((x+y)/2,(x-y)/2) $:原坐标系中的切比雪夫距离=新坐标系中的曼哈顿距离。

       $ (x,y)-> (x+y,x-y) $:原坐标系中曼哈顿距离=新坐标系中切比雪夫距离。

  然后转坐标系,x,y坐标分开处理,前缀和搞一下就好了。

  代码:

#include<cstdio>
#include<algorithm>
#define ll long long
#define min(a,b) (a<b?a:b)
#define maxn 100010
inline ll read()
{
    ll x=0; char c=getchar(),f=1;
    for(;c<'0'||'9'<c;c=getchar())if(c=='-')f=0;
    for(;'0'<=c&&c<='9';c=getchar())x=x*10+c-'0';
    return f?x:-x;
}
struct data{
    double x,y;
    int id;
}a[maxn];
double sum[maxn],ansx[maxn],ansy[maxn];
int n;
bool cmp1(data a,data b){return a.x<b.x;}
bool cmp2(data a,data b){return a.y<b.y;}
int main()
{
    n=read();
    for(int i=1;i<=n;i++){
        int x=read(),y=read();
        a[i].x=1.0*(x+y)/2; a[i].y=1.0*(x-y)/2; a[i].id=i;
    }
    std::sort(a+1,a+n+1,cmp1);
    sum[0]=0;
    for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+a[i].x;
    for(int i=1;i<=n;i++)
        ansx[a[i].id]=(a[i].x*(i-1)-sum[i-1])+(sum[n]-sum[i]-a[i].x*(n-i));
    std::sort(a+1,a+n+1,cmp2);
    sum[0]=0;
    for(int i=1;i<=n;i++)
        sum[i]=sum[i-1]+a[i].y;
    for(int i=1;i<=n;i++)
        ansy[a[i].id]=((a[i].y*(i-1)-sum[i-1])+(sum[n]-sum[i]-a[i].y*(n-i)));
    double mn=1ll<<60;
    for(int i=1;i<=n;i++)
        mn=min(mn,(ansx[i]+ansy[i]));
    printf("%.0lf\n",mn);
}
bzoj3170

  另一道练习题:花神的浇花集会

posted @ 2018-10-01 21:53  QuartZ_Z  阅读(222)  评论(0编辑  收藏  举报