0
点赞
收藏
分享

微信扫一扫

HDOJ  4311  Meeting point-1


题目:​​http://acm.hdu.edu.cn/showproblem.php?pid=4311​​

题解报告:

平面上两点间的 Manhattan 距离为 |x1-x2| + |y1-y2|


X 方向的距离与 Y 方向上的距离可以分开来处理。假设我们以 (xi,yi) 作为开会的地点,那么其余的点到该开会地点所需的时间为 X 方向上到 xi 所需要的时间加上 Y 方向上到 yi 所需要的时间。

对数据预处理后可以快速地求出x坐标小于xi的点的个数rankx, 并且这些 x 坐标值之和 sumx,那么这些点 X 方向上对结果的贡献为 rankx * xi - sumx;同理可以处理出 x 坐标大于 xi 的点在 X 方向上对结果的贡献值。同理可求得其余点在 Y 方向上到达 yi 所需要的总时间。


#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef long long ll;
const int MAXN = 100100;
struct Point{
int x, y;
Point(){}
Point(int _x, int _y):x(_x),y(_y){}
}ary[MAXN];
int x[MAXN], y[MAXN];
ll sx[MAXN], sy[MAXN];
int main()
{
int T, n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i = 0; i < n; ++i)
{
scanf("%d%d",&x[i],&y[i]);
ary[i] = Point(x[i], y[i]);
}
sort(x, x + n);
sort(y, y + n);
sx[0] = x[0];
sy[0] = y[0];
for(int i = 1; i < n; ++i)
{
sx[i] = sx[i - 1] + x[i];
sy[i] = sy[i - 1] + y[i];
}
ll ans = 1;
ans <<= 60;
for(int i = 0; i < n; ++i)
{
int rankx = lower_bound(x, x + n, ary[i].x) - x;
int ranky = lower_bound(y, y + n, ary[i].y) - y;
+sx[n - 1] - sx[rankx] - ll(ary[i].x) * (n - rankx - 1);
+sy[n - 1] - sy[ranky] - ll(ary[i].y) * (n - ranky - 1);
//其实上面这两步都可以化简的,只不过为了表明意思而已
ans = min(ans, t);
}
cout<<ans<<endl;
}
return 0;
}

举报

相关推荐

0 条评论