HDU 4311
题意
二维坐标系上给出n个点,要求在n个点中选定一个点作为中点,使得其它所有点到该点的曼哈顿距离之和最小
曼哈顿距离也叫都市距离,计算公式
d = |x1-x2|+|y1-y2|
解决
x轴和y轴独立,分开来做
枚举每一个点当做中点的情况,但是n^2的算法会超时
- 按x坐标升序排序
- 第一个点扫n-1次求得以第一个点作为中点的x轴距离之和
- 以
sumx[i] = sum[i-1]+(2*(i-1)-n)*(node[i].x-node[i-1].x);
进行递推 - 上面的式子可以这样思考,从i-1到i,前面有i-1个点,需要加上(i-1)(node[i].x-node[i-1].x),后面(包括他自己)有n-(i-1)个点,又要再减去(n-(i-1))(node[i].x-node[i-1].x)
struct Node
{
ll x,y;
int id;
Node(){}
Node(ll xx,ll yy,int ii){
x = xx;
y = yy;
id = ii;
}
};
bool cmpx(Node n1 , Node n2) { return n1.x < n2.x; }
bool cmpy(Node n1 , Node n2) { return n1.y < n2.y; }
Node node[maxn];
ll sumx[maxn] , sumy[maxn];
int main()
{
int T;
ll x,y;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
rep(i,1,n+1){
scanf("%lld%lld",&x,&y);
node[i] = Node(x,y,i);
}
sort(node+1,node+1+n,cmpx);
sumx[node[1].id] = 0;
rep(i,2,n+1) sumx[node[1].id]+=node[i].x-node[1].x;
rep(i,2,n+1) sumx[node[i].id] = sumx[node[i-1].id]+(2*(i-1)-n)*(node[i].x-node[i-1].x);
//rep(i,1,n+1) printf("%3d%c",i,i==n?'\n':' ');
//rep(i,1,n+1) printf("%3lld%c",sumx[node[i].id],i==n?'\n':' ');
sort(node+1,node+1+n,cmpy);
sumy[node[1].id] = 0;
rep(i,2,n+1) sumy[node[1].id]+=node[i].y-node[1].y;
rep(i,2,n+1) sumy[node[i].id] = sumy[node[i-1].id]+(2*(i-1)-n)*(node[i].y-node[i-1].y);
//rep(i,1,n+1) printf("%3lld%c",sumx[node[i].id],i==n?'\n':' ');
ll ans = INF;
rep(i,1,n+1) ans = min(ans , sumx[node[i].id]+sumy[node[i].id]);
cout<<ans<<endl;
}
}
HDU 4312
题意
一个点可以在1个时间内到达相邻的八连通块,了解一下切比雪夫距离可以知道这个也就是切比雪夫距离
求解切比雪夫距离可以对变换后的坐标求解曼哈顿距离得到
//对于(x,y),将其转换为切比雪夫坐标(x+y,x-y)
//求曼哈顿距离(都市距离)之后除以2就是切比雪夫距离
struct Node
{
ll x,y;
int id;
Node(){}
Node(ll xx,ll yy,int ii){
x = xx;
y = yy;
id = ii;
}
};
bool cmpx(Node n1 , Node n2) { return n1.x < n2.x; }
bool cmpy(Node n1 , Node n2) { return n1.y < n2.y; }
Node node[maxn];
ll sumx[maxn] , sumy[maxn];
int main()
{
int T;
ll x,y;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
rep(i,1,n+1){
scanf("%lld%lld",&x,&y);
node[i] = Node(x+y,x-y,i);
}
sort(node+1,node+1+n,cmpx);
sumx[node[1].id] = 0;
rep(i,2,n+1) sumx[node[1].id]+=node[i].x-node[1].x;
rep(i,2,n+1) sumx[node[i].id] = sumx[node[i-1].id]+(2*(i-1)-n)*(node[i].x-node[i-1].x);
//rep(i,1,n+1) printf("%3d%c",i,i==n?'\n':' ');
//rep(i,1,n+1) printf("%3lld%c",sumx[node[i].id],i==n?'\n':' ');
sort(node+1,node+1+n,cmpy);
sumy[node[1].id] = 0;
rep(i,2,n+1) sumy[node[1].id]+=node[i].y-node[1].y;
rep(i,2,n+1) sumy[node[i].id] = sumy[node[i-1].id]+(2*(i-1)-n)*(node[i].y-node[i-1].y);
//rep(i,1,n+1) printf("%3lld%c",sumx[node[i].id],i==n?'\n':' ');
ll ans = INF;
rep(i,1,n+1) ans = min(ans , sumx[node[i].id]+sumy[node[i].id]);
cout<<ans/2<<endl;
}
}