雜題 [Tjoi 2013]松鼠聚會

問題 F: [Tjoi 2013]松鼠聚會
時間限制: 1 Sec 內存限制: 128 MB
提交: 70 解決: 35
[提交][狀態][討論版]
題目描述
有N個小松鼠,它們的家用一個點x,y表示,兩個點的距離定義爲:點(x,y)和它周圍的8個點即上下左右四個點和對角的四個點,距離爲1。現在N個松鼠要走到一個松鼠家去,求走過的最短距離。

輸入
第一行給出數字N,表示有多少隻小松鼠。0<=N<=10^5
下面N行,每行給出x,y表示其家的座標。
-10^9<=x,y<=10^9

輸出
表示爲了聚會走的路程和最小爲多少。

樣例輸入
6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
樣例輸出
20

題目中要求的是切比雪夫距離,但這個太麻煩了。其實切比雪夫距離是可以轉化成曼哈頓距離的,切比雪夫距離公式:S=max(ax-bx,ay-by)等於(ax+ay,ax-ay)和(bx+by,bx-by)兩點的曼哈頓距離。想要證明只要把那個曼哈頓距離求出來化簡即可。
那麼就容易了,搞一個前綴和,二分出做減法的邊界,掃一遍就行了。

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#define N 100005
#define inf 1000000000
#define ll long long
struct node{int x,y;}a[N];
int n,mn=inf,mx=-inf,bx[N],by[N];ll ans=inf*10000000ll,sumx[N],sumy[N];
using namespace std;
int main()
{
    scanf("%d",&n);int x,y;
    for(int i=1;i<=n;i++)
    {
       scanf("%d%d",&x,&y);
       a[i].x=x+y,a[i].y=x-y;
       bx[i]=a[i].x;by[i]=a[i].y;
    }
    sort(bx+1,bx+n+1);
    sort(by+1,by+n+1);
    for(int i=1;i<=n;i++)
       sumx[i]=sumx[i-1]+bx[i],sumy[i]=sumy[i-1]+by[i];
    for(int i=1;i<=n;i++)
    {
        ll h=0;ll l;
        l=lower_bound(bx+1,bx+n+1,a[i].x)-bx;
        h+=(l*2-n)*a[i].x*1ll-sumx[l]*2+sumx[n];
        l=lower_bound(by+1,by+n+1,a[i].y)-by;
        h+=(l*2-n)*a[i].y*1ll-sumy[l]*2+sumy[n];
        if(h<ans)ans=h;
    }
    printf("%lld\n",ans/2);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章