【切比雪夫距離轉曼哈頓距離】棋盤問題
【題目描述】
小O 對國際象棋有著濃厚的興趣,因為他水平高超,每次人機對戰他總是輕鬆獲勝,所
以他決定自己跟自己下國際象棋。
小O 的棋盤非常大,達到了 10^9*10^9,現在他在棋盤上擺放了 n 個國王,並對你提出
了q次詢問,每次詢問指定一個座標,問將所有國王從初始位置全部移動到這個座標所需要
的最小步數是多少,詢問之間相互獨立,也就是說每次詢問結束後國王會全部回到原來位置。
注意:由於小 O擔心大家無法理解過於高深的規則,所以在本題中,國王之間不會發生
相互攻擊而且多個國王可以同時處在一個格子中, 國際象棋中國王一步只能移動到與其八
連通的格子中。
【輸入格式】
第一行一個正整數 T表示資料組數。
對於每組資料,共有(n+q+1)行:
第一行兩個數字 n,q分別表示國王數量和詢問數量。
接下來n行,每行兩個數字 Kxi,Kyi表示國王所在座標。
接下來q行,每行兩個數字 Txi,Tyi表示目標座標。
【輸出格式】
對於每組資料,輸出共有q行,每行一個整數表示對應詢問的答案。
【輸入樣例】
1
1 1
233 666
666 233
【輸出樣例】
433
【資料範圍】
N<=1000000,Q<=1000000,
本題共7個測試點,不採用 subtask評測,但每個測試點分值不同.
資料範圍中的 X,Y範圍表示Kxi,Kyi,Txi,Tyi的範圍,未標註即為沒有特殊限制
對於全部資料,滿足 N的總和不超過10^6 且Q 的總和不超過10^6,輸入檔案中所有數
字均為正整數且不超過 10^9.
#1:1pt,滿足T=n=q=X=Y=1;
#2:3pts,滿足 T=1,1<=X,Y<=5,1<=n<=5,q=1;
#3:16pts,滿足 T=1,1<=X,Y<=5,1<=n<=5;
#4:11pts,滿足 T=1,1<=X,Y<=1000,1<=n,q<=5000;
#5:21pts,滿足所有資料中 N*Q的總和不超過 5*10^7;
#6:22pts,滿足 T=1,1<=X,Y<=1000;
#7:26pts,無特殊限制。
這道題其實就是求所有點到一個點的切比雪夫距離之和。我們把它轉化成曼哈頓距離就行了。
具體見程式碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll maxn=1e6+233; inline void read(ll &x){ x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); } ll x[maxn],y[maxn]; ll sumx[maxn],sumy[maxn]; ll n,q,T,X,Y,tx,ty; ll ans; int main(){ read(T); while(T--){ read(n),read(q); for(ll i=1;i<=n;++i) read(tx),read(ty),x[i]=tx+ty,y[i]=tx-ty; //轉化座標 sort(x+1,x+1+n),sort(y+1,y+1+n); //座標排序 for(ll i=1;i<=n;++i) sumx[i]=sumx[i-1]+x[i],sumy[i]=sumy[i-1]+y[i]; //座標字首和 for(ll i=1;i<=q;++i){ ll ans=0; read(tx),read(ty); X=tx+ty,Y=tx-ty; ll pos=lower_bound(x+1,x+n+1,X)-x; ans+=(pos-1)*X-sumx[pos-1]+sumx[n]-sumx[pos-1]-(n-pos+1)*X; pos=lower_bound(y+1,y+n+1,Y)-y; ans+=(pos-1)*Y-sumy[pos-1]+sumy[n]-sumy[pos-1]-(n-pos+1)*Y; printf("%lld\n",ans/2); } } }
其中橫座標的曼哈頓距離和縱座標的曼哈頓距離是類似的,也是獨立的。下面拿橫座標的舉個梨子把。
我們要求的就是Σ|x[i]-X|。x[1]到x[pos-1]是小於X的,絕對值拆開就是X-x[i],後面的就是x[i]-X。Y同理。