http://acm.hdu.edu.cn/showproblem.php?pid=4311
http://acm.hdu.edu.cn/showproblem.php?pid=4312
4311求最小空间曼哈顿距离之和 4312求最小空间切比雪夫距离之和
空间三种距离总结http://www.cnblogs.com/adelalove/p/8612540.html
曼哈顿距离
在曼哈顿距离中x与y互不想干 分别排序后求一个前缀后缀即可
如果答案不要求在某一个点上的话 直接对每个维度排序取中位数
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=0x3f3f3f3f3f3f3f3f;
struct node
{
ll x,y;
int id;
};
node point[100010];
ll pre[100010],post[100010];
int n;
bool cmpI(node n1,node n2)
{
return n1.x<n2.x;
}
bool cmpII(node n1,node n2)
{
return n1.y<n2.y;
}
ll getmin(ll a,ll b)
{
if(a<b) return a;
else return b;
}
int main()
{
ll i,sum,ans;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
point[i].id=i;
scanf("%lld%lld",&point[i].x,&point[i].y);
}
memset(pre,0,sizeof(pre));
memset(post,0,sizeof(post));
sort(point+1,point+n+1,cmpI);
sum=0;
for(i=2;i<=n;i++)
{
sum+=(i-1)*(point[i].x-point[i-1].x);
pre[point[i].id]+=sum;
}
sum=0;
for(i=n-1;i>=1;i--)
{
sum+=(n-i)*(point[i+1].x-point[i].x);
post[point[i].id]+=sum;
}
sort(point+1,point+n+1,cmpII);
sum=0;
for(i=2;i<=n;i++)
{
sum+=(i-1)*(point[i].y-point[i-1].y);
pre[point[i].id]+=sum;
}
sum=0;
for(i=n-1;i>=1;i--)
{
sum+=(n-i)*(point[i+1].y-point[i].y);
post[point[i].id]+=sum;
}
ans=N;
for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]);
printf("%lld\n",ans);
}
return 0;
}
切比雪夫距离
想不到 数学太差 做题太少
对于两点(x1,y1) (x2,y2)
dis = max(x2-x1,y2-y1) = ( |(x2-x1)+(y2-y1)| + |(x2-x1)-(y2-y1)| ) / 2 = ( |(x2+y2)-(x1+y1)| + |(x2-y2)-(x1-y1)| ) / 2
注:x2-x1>=0 y2-y1>=0
这样就把求(x1,y1) (x2,y2)之间切比雪夫距离转换为求(x1+y1,x1-y1) (x2+y2,x2-y2)之间曼哈顿距离的问题
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=0x3f3f3f3f3f3f3f3f;
struct node
{
ll x,y;
int id;
};
node point[100010];
ll pre[100010],post[100010];
int n;
bool cmpI(node n1,node n2)
{
return n1.x<n2.x;
}
bool cmpII(node n1,node n2)
{
return n1.y<n2.y;
}
ll getmin(ll a,ll b)
{
if(a<b) return a;
else return b;
}
int main()
{
ll i,x,y,sum,ans;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
point[i].id=i;
scanf("%lld%lld",&x,&y);
point[i].x=x+y,point[i].y=x-y;
}
memset(pre,0,sizeof(pre));
memset(post,0,sizeof(post));
sort(point+1,point+n+1,cmpI);
sum=0;
for(i=2;i<=n;i++)
{
sum+=(i-1)*(point[i].x-point[i-1].x);
pre[point[i].id]+=sum;
}
sum=0;
for(i=n-1;i>=1;i--)
{
sum+=(n-i)*(point[i+1].x-point[i].x);
post[point[i].id]+=sum;
}
sort(point+1,point+n+1,cmpII);
sum=0;
for(i=2;i<=n;i++)
{
sum+=(i-1)*(point[i].y-point[i-1].y);
pre[point[i].id]+=sum;
}
sum=0;
for(i=n-1;i>=1;i--)
{
sum+=(n-i)*(point[i+1].y-point[i].y);
post[point[i].id]+=sum;
}
ans=N;
for(i=1;i<=n;i++) ans=getmin(ans,pre[i]+post[i]);
printf("%lld\n",ans/2);
}
return 0;
}