博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[TJOI2013]松鼠聚会 BZOJ 3170
阅读量:6187 次
发布时间:2019-06-21

本文共 3162 字,大约阅读时间需要 10 分钟。

题目描述

草原上住着一群小松鼠,每个小松鼠都有一个家。时间长了,大家觉得应该聚一聚。但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理。

每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为点(x,y)和它周围的8个点(x-1,y)(x+1,y),(x,y-1),(x,y+1).(x-1,y+1),(x-1,y-1),(x+1,y+1),(x+1,y-1)距离为1。

输入输出格式

输入格式:

第一行是一个整数N,表示有多少只松鼠。接下来N行,第i行是两个整数x和y,表示松鼠i的家的坐标

输出格式:

一个整数,表示松鼠为了聚会走的路程和最小是多少。

输入输出样例

输入样例#1:
6-4 -1-1 -22 -40 20 35 -2
输出样例#1:
20
输入样例#2:
60 02 0-5 -22 -2-1 24 0
输出样例#2:
15

说明

样例解释

在第一个样例中,松鼠在第二只松鼠家(-1,-2)聚会;在第二个样例中,松鼠在第一只松鼠家(0.0)聚会。

数据范围

30%的数据,0 ≤ N ≤ 1000

100%的数据,0 ≤ N ≤ 100000; −10^9 ≤ x, y ≤ 10^9

 

 

首先我们要求的是 切比雪夫距离。

也就是 dis=max( |dx|,|dy|);

看样子可能不太好求解;

想办法转换为 曼哈顿距离;

在(x,y)坐标系中进行变换----> ( (x+y)/2,(x-y)/2 );

可以发现原坐标系中的 切比雪夫距离 就是新坐标系中的 曼哈顿距离 ;

(推一下即可);

 

那么我们考虑用 曼哈顿距离求解:

Mdis(i,k) 即该值最小;

将其变为有序方便处理(不妨设为升序);

即 Mdis(1,i)+Mdis(2,i)+...+Mdis(n,i)

现以X坐标为例:

即 x[ i ]-x[ 1 ]+x[ i ]-x[ 2 ]+...+x[ i+1 ]-x[ i ]+...x[ n ]-x[ i ]

= i*x[ i ]- sum[ i ]+sum[ n ]-sum[ i ]+(n-i)*x[ i ];

那么就可以用前缀和进行维护了;

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#pragma GCC optimize("O3")using namespace std;#define maxn 300005#define inf 0x3f3f3f3f#define INF 9999999999#define rdint(x) scanf("%d",&x)#define rdllt(x) scanf("%lld",&x)#define rdult(x) scanf("%lu",&x)#define rdlf(x) scanf("%lf",&x)#define rdstr(x) scanf("%s",x)typedef long long ll;typedef unsigned long long ull;typedef unsigned int U;#define ms(x) memset((x),0,sizeof(x))const long long int mod = 1e9 + 7;#define Mod 1000000000#define sq(x) (x)*(x)#define eps 1e-3typedef pair
pii;#define pi acos(-1.0)//const int N = 1005;#define REP(i,n) for(int i=0;i<(n);i++)inline ll rd() { ll x = 0; char c = getchar(); bool f = false; while (!isdigit(c)) { if (c == '-') f = true; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f ? -x : x;}ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b);}ll sqr(ll x) { return x * x; }/*ll ans;ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ans = exgcd(b, a%b, x, y); ll t = x; x = y; y = t - a / b * y; return ans;}*/ll qpow(ll a, ll b, ll c) { ll ans = 1; a = a % c; while (b) { if (b % 2)ans = ans * a%c; b /= 2; a = a * a%c; } return ans;}int n;int x[maxn], y[maxn];ll ans, tmp, sumx[maxn], sumy[maxn];struct node { ll x, y;}a[maxn];int main(){ //ios::sync_with_stdio(0); rdint(n); for (int i = 1; i <= n; i++) { int xx, yy; rdint(xx); rdint(yy); x[i] = a[i].x = xx + yy; y[i] = a[i].y = xx - yy; } sort(x + 1, x + 1 + n); sort(y + 1, y + 1 + n); for (int i = 1; i <= n; i++) sumx[i] = sumx[i - 1] + x[i], sumy[i] = sumy[i - 1] + y[i]; ans = 100000000000000000; for (int i = 1; i <= n; i++) { int pos = lower_bound(x + 1, x + 1 + n, a[i].x) - x; tmp = sumx[n] - sumx[pos] - a[i].x*(n - pos) + pos * a[i].x - sumx[pos]; pos = lower_bound(y + 1, y + 1 + n, a[i].y) - y; tmp += sumy[n] - sumy[pos] - a[i].y*(n - pos) + a[i].y*pos - sumy[pos]; ans = min(ans, tmp); } cout << ans / 2 << endl; return 0;}

 

转载于:https://www.cnblogs.com/zxyqzy/p/10040810.html

你可能感兴趣的文章
联系方式
查看>>
更新yum为国内yum源
查看>>
Python开发工具PyCharm个性化设置(图解)
查看>>
分析Zookeeper的一致性原理
查看>>
学习日志---基本排序算法
查看>>
关于Forms_ddl的应用
查看>>
创建并管理esxi网络
查看>>
Android viewHolder处理listView滑动
查看>>
Apache在windows下的安装
查看>>
gulp API 简介
查看>>
项目经理的权宜之计
查看>>
redis应用之使用sentinel实现主从复制高可用
查看>>
软件工程院校排名
查看>>
Excle 创建下拉列表
查看>>
SSH原理之图文详解
查看>>
yum的repo文件详解、以及epel简介、yum源的更换
查看>>
我的友情链接
查看>>
第 三 十 九 天:更 换 yum 源 和 卸 载 图 形 界 面
查看>>
1,Python13_day1
查看>>
flask-uploads扩展的使用
查看>>