题解:P3439 [POI2006] MAG-Warehouse
BuQiuRu4587 · · 题解
来点无脑做法。
首先把切比雪夫距离转化成曼哈顿距离。
具体来说,对于点
那么现在可以把所有点
变成曼哈短距离最大的好处就是把横纵坐标的
先做答案的横坐标
直接把
于是就做完了。
但是还有一个问题,最后复原答案的时候有一步要除一个
代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
struct node{
int x,k;
}a[100005],b[100005];
int x[100005],y[100005],k[100005];
signed main(){
cin>>n;
__int128 s=0;
for(int i=1;i<=n;i++){
cin>>x[i]>>y[i]>>k[i];
s+=k[i];
a[i].x=x[i]+y[i];
b[i].x=x[i]-y[i];
a[i].k=b[i].k=k[i];
}
sort(a+1,a+1+n,[](node x,node y){
return x.x<y.x;
});
sort(b+1,b+1+n,[](node x,node y){
return x.x<y.x;
});
int pos1=0,pos2=0,t=0;
for(int i=n;i;i--){
t+=a[i].k;
if(t*2>=s){
pos1=a[i].x;
break;
}
}
t=0;
for(int i=n;i;i--){
t+=b[i].k;
if(t*2>=s){
pos2=b[i].x;
break;
}
}
int X=pos1+pos2;
int Y=pos1-pos2;
X>>=1,Y>>=1;
__int128 minn=1e30;
int ansx=0,ansy=0;
for(int i=-2;i<=2;i++){
for(int j=-2;j<=2;j++){
if(X+i<1||X+i>5e8||Y+j<1||Y+j>5e8) continue;
s=0;
for(int p=1;p<=n;p++){
s+=max(abs(X+i-x[p]),abs(Y+j-y[p]))*k[p];
}
if(s<minn){
minn=s;
ansx=X+i;
ansy=Y+j;
}
}
}
cout<<ansx<<' '<<ansy<<'\n';
}