BZOJ 1516 [POI2006]Mag-Warehouse 切比雪夫距离转曼哈顿距离

题意:

给定一个网格图,其上有一堆坏点(整点,同一位置多个),求一个整点,使得该整点到所有的坏点的切比雪夫距离之和最小。

求这个整点位置。

无SPJ

解析:

看完题懵了,我只会曼哈顿距离啊怎么办。

然后就无聊查了下给定的那个计算公式,哇塞这居然叫切比雪夫距离。

噫怎么有个链接是谈切比雪夫转化曼哈顿距离的。

噫看完后我就会这道题辣!

对于原坐标系中两点间的 Chebyshev 距离,是将坐标轴顺(逆)时针旋转45度并将所有点的坐标值放大sqrt(2)倍所得到的新坐标系中的Manhattan距离的二分之一。

某点绕原点逆时针旋转α°(或坐标轴顺时针旋转)后,点(x,y)的坐标会变为(cosα*x - sinα*y , sinα*x + cosα*y)。

有了以上两个东西这题就解辣

显然点(x,y)逆时针旋转45度坐标值放大sqrt(2)倍后的坐标是(x-y,x+y)。

于是我们直接把所有点搞过去,分别求x,y的中位数即可。

然后转回来的点有两种:第一坐标都是整数那么直接输出即可。

第二坐标有不是整数的(即.5)我们需要判断floor(x),ceil(x),floor(y),ceil(y)任意组成的点的距离。

这个复杂度O(n)不怂。

你问我没有SPJ这题怎么做?

登陆main.edu.pl,搞到所有数据,求中位数的时候按照他的意思求,取左边或者右边我忘了,答案坐标非整数判断的时候按照他的意思取最终答案(好像是横纵坐标最大)。

赶紧来人写SPJ!

代码:

#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100100
#define eps 1e-8
using namespace std;
typedef long long ll;
int n;
ll sum;
struct node
{
    ll x,y,t;
    friend istream& operator >> (istream &_,node &a)
    {scanf("%lld%lld%lld",&a.x,&a.y,&a.t);sum+=a.t;return _;}
}pt[N];
map<ll,int>mx,my;
int totx,toty;
struct arr
{
    ll val,num;
}arrx[N],arry[N];
bool cmp(arr a,arr b)
{
    return a.val<b.val;
}
ll sumx[N],sumy[N];
ll xx[5],yy[5];
int main()
{
    #ifndef ONLINE_JUDGE
        freopen("mag.in","r",stdin);
        freopen("mag.out","w",stdout);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++)cin>>pt[i];
    for(int i=1;i<=n;i++)
    {
        ll x=pt[i].x-pt[i].y,y=pt[i].x+pt[i].y;
        if(!mx[x])
            mx[x]=++totx,arrx[totx].val=x,arrx[totx].num=pt[i].t;
        else arrx[mx[x]].num+=pt[i].t;
        if(!my[y])
            my[y]=++toty,arry[toty].val=y,arry[toty].num=pt[i].t;
        else arry[my[y]].num+=pt[i].t;
    }
    sort(arrx+1,arrx+totx+1,cmp);
    sort(arry+1,arry+toty+1,cmp);
    for(int i=1;i<=totx;i++)sumx[i]=sumx[i-1]+arrx[i].num;
    for(int i=1;i<=toty;i++)sumy[i]=sumy[i-1]+arry[i].num;
    int flag=0;
    if(!(sum&1))flag=1;
    sum>>=1;
    double midX=0,midY=0;
    int l=1,r=totx,ans=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(sumx[mid]<=sum)ans=mid,l=mid+1;
        else r=mid-1;
    }
    if(flag)
    {
        if(sumx[ans]==sum)midX=arrx[ans].val;
        else midX=arrx[ans+1].val;
    }else midX=arrx[ans+1].val;
    l=1,r=toty,ans=0;
    while(l<=r)
    {
        int mid=(l+r)>>1;
        if(sumy[mid]<=sum)ans=mid,l=mid+1;
        else r=mid-1;
    }
    if(flag)
    {
        if(sumy[ans]==sum)midY=arry[ans].val;
        else midY=arry[ans+1].val;
    }else midY=arry[ans+1].val;
    double prex=(midX+midY)/2;
    double prey=(midY-midX)/2;
    if(prex-floor(prex)>eps||prey-floor(prey)>eps)
    {
        xx[1]=xx[2]=(ll)floor(prex),xx[3]=xx[4]=(ll)ceil(prex);
        yy[1]=yy[3]=(ll)floor(prey),yy[2]=yy[4]=(ll)ceil(prey);
        ll sum=-1,no;
        for(int i=1;i<=4;i++)
        {
            ll ret=0;
            for(int j=1;j<=n;j++)
            {
                ll tmpx=pt[j].x-xx[i],tmpy=pt[j].y-yy[i];
                if(tmpx<0)tmpx=-tmpx;if(tmpy<0)tmpy=-tmpy;
                ret+=pt[j].t*(max(tmpx,tmpy));
            }
            if(sum==-1||ret<=sum)
            {sum=ret,no=i;}
        }
        printf("%lld %lld\n",xx[no],yy[no]);
    }else
    {
        printf("%lld %lld\n",(ll)prex,(ll)prey);
    }

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-18 19:24:57

BZOJ 1516 [POI2006]Mag-Warehouse 切比雪夫距离转曼哈顿距离的相关文章

BZOJ 2735: 世博会 主席树+切比雪夫距离转曼哈顿距离

2735: 世博会 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 124  Solved: 51[Submit][Status][Discuss] Description 四年一度的世博会又要举办了,Q国很荣幸成为了这次世博会的主办方.Q国主席QQ从全国各地收集了N件物品排成 一排,作为Q国馆的展出物.对于相邻摆放的一些物品,如果过于相似会让人觉得无聊,如果差别过大又会让人觉 得突兀.为了让人们对这次世博会的展出满意,QQ需要知道一些相邻物品的“

各种距离 欧式距离、曼哈顿距离、切比雪夫距离、闵可夫斯基距离、标准欧氏距离、马氏距离、余弦距离、汉明距离、杰拉德距离、相关距离、信息熵

1. 欧氏距离(Euclidean Distance) 欧氏距离是最容易直观理解的距离度量方法,我们小学.初中和高中接触到的两个点在空间中的距离一般都是指欧氏距离. 二维平面上点a(x1,y1)与b(x2,y2)间的欧氏距离: 三维空间点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离: n维空间点a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的欧氏距离(两个n维向量): Matlab计算欧氏距离: Matlab计算距离使用pdist函数.若X是一个m×n的矩阵,

HDU 4312 最小切比雪夫距离-转化成曼哈顿距离再分治

题意:二维空间,n个点,求以某点为起点到各点的最小切比雪夫距离 分析: 上一道题之前已经用"分治"思想在O(n)的时间内求出了n个点,以某点为起点到各点的最小曼哈顿距离,那么我们根据二维空间切比雪夫距离和曼哈顿距离的关系,可以把切比雪夫距离转化成曼哈顿距离,再直接用之前的方法即可. 二维空间: 曼哈顿距离 :d=|x1-x2|+|y1-y2|,到某点的曼哈顿距离为r的点组成一个边长为√2*r的正方形,且边与坐标轴成45度 切比雪夫距离:d=max(|x1-x2|,|y1-y2|),到某

1062. 计算曼哈顿距离

题目描述 给出平面上两个点的坐标(x1,y1),(x2,y2),求两点之间的曼哈顿距离.曼哈顿距离=|x1-x2|+|y1-y2|. 输入 一行四个空格隔开的实数,分别表示x1,y1,x2,y2. 输出 输出一个实数表示曼哈顿距离,保留三位小数. 样例输入 输出一个实数表示曼哈顿距离,保留三位小数. 样例输出 3.600 数据范围限制 -10000<=x1,y1,x2,y2<=10000 1 #include<iostream> 2 #include<cstring>

Atitti knn实现的具体四个距离算法 欧氏距离、余弦距离、汉明距离、曼哈顿距离

Atitti knn实现的具体四个距离算法  欧氏距离.余弦距离.汉明距离.曼哈顿距离 1. Knn算法实质就是相似度的关系1 1.1. 文本相似度计算在信息检索.数据挖掘.机器翻译.文档复制检测等领域有着广泛的应用1 2. 汉明距离1 2.1. 历史及应用1 3. 曼哈顿距离2 3.1. SimHash + 汉明距离3 3.2. .简单共有词4 1. Knn算法实质就是相似度的关系 1.1. 文本相似度计算在信息检索.数据挖掘.机器翻译.文档复制检测等领域有着广泛的应用 数据挖掘的过程中,只用

POJ 3241 Object Clustering 二维平面曼哈顿距离最小生成树

题目链接:点击打开链接 题意: 给定二维平面上的n个点坐标,常数k 下面n行给出坐标 求一个最小生成树,问第k大的边是多少. 任意两个点间建一条边的花费是其曼哈顿距离. 思路:转自:点击打开链接 一.曼哈顿距离最小生成树 曼哈顿距离最小生成树问题可以简述如下: 给定二维平面上的N个点,在两点之间连边的代价为其曼哈顿距离,求使所有点连通的最小代价. 朴素的算法可以用O(N2)的Prim,或者处理出所有边做Kruskal,但在这里总边数有O(N2)条,所以Kruskal的复杂度变成了O(N2logN

bzoj 3170 Tjoi 2013 松鼠聚会 曼哈顿距离&amp;&amp;切比雪夫距离

因为曼哈顿距离很好求,所以要把每个点的坐标转换一下. 转自:http://blog.csdn.net/slongle_amazing/article/details/50911504 题解 两个点的切比雪夫距离为d=max(|x1?x2|,|y1?y2|)   写一下曼哈顿距离的常用处理方法 两个点(x1,y2),(x2,y2) 其曼哈顿距离=|x1?x2|+|y1?y2| 因为|x1?x2|=max(x1?x2,x2?x1) 所以可以写成=max(x1?x2+y1?y2,x1?x2+y2?y1

HDU 4311&amp;4312 Meeting point-1&amp;2 (曼哈顿距离&amp;&amp;切比雪夫距离)

HDU 4311 题意:平面上有n个点,一个点(x,y)只能到达(x-1,y), (x+1,y), (x, y-1), (x, y+1)4个点.从n个点中找到一点,使其他点到此点的距离之和最小. 思路: 可以发现,两个点间距离为 |x1-x2| + |y1-y2| ,这便是两点间的曼哈顿距离. 朴素的做法是遍历所有点,枚举该点与其他点间的曼哈顿距离之和,但是会TLE: 取巧的做法是将所有点与中心点的曼哈顿距离排序,枚举中间大概250个点左右的情况比较即可(不要欺负人家数据水! 正确姿势: 用结构

HDU4312 Meeting point-2 (切比雪夫距离&amp;&amp;曼哈顿距离)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4312 题意:给定平面坐标上n(n<=100000)个点,然后在其中选一个,使得所有点到当前点的Chebyshev距离和最小. 分析: 切比雪夫距离:设a(x1,y1),b(x2,y2);DIS = max(|x1-x2|,|y1-y2|) = (|x1-x2+y1-y2|+|x1-x2-y1+y2|)/2; 我们将点aa的坐标看成(x1+y1,x1-y1),bb的坐标看成(x2+y2,x2-y2)