BZOJ 1516 [POI2006]Mag-Warehouse 切比雪夫距離轉曼哈頓距離

來源:互聯網
上載者:User

標籤:poi   網格   

題意:
給定一個網格圖,其上有一堆壞點(整點,同一位置多個),求一個整點,使得該整點到所有的壞點的切比雪夫距離之和最小。
求這個整點位置。

無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-8using 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);    }}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

BZOJ 1516 [POI2006]Mag-Warehouse 切比雪夫距離轉曼哈頓距離

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.