题意

B 君的第三题(zhengzhou)

题目描述

让你在战争和耻辱中做一块选择,你选择耻辱,可你将来还得进行战争。

在平面上有n 个整点(横纵坐标都是整数)

B 君想找到一个整点,使得这个点,到所有点的距离之和最小。

两个点的距离定义为从一个点到到另一个点的最小步数。

其中每步可以走向相邻8 个点(上,下,左,右,左上,左下,右上,右下,类似国际象棋中的王)走一步。

输出这个最小的距离之和。

和这个点选择的方案数。(即有多少个点,可以达到这个最小的距离)

输入格式

第一行一个整数n 表示点数。

接下来n 行,每行两个整数x, y。描述一个点。

输出格式

第一行输出最小的距离之和。

第二行输出有多少个点,可以达到这个最小距离。

样例输入一

4

0 0

0 2

2 0

2 2

样例输出一

4

1

样例解释一

选择(1, 1)。

样例输入二

4

2 1

1 2

0 1

1 0

样例输出二

4

5

样例解释二

可以选择输入的4 个点之一,或者(1, 1)。

样例输入三

3

0 1

1 0

0 0

样例输出三

2

3

样例解释三

可以选择输入的3 个点之一。

数据规模与约定

对于100% 的数据,满足\(1 \leq n \leq 10^5,|x|, |y| \leq 10^9\)。

对于40% 的数据,满足\(1 \leq n \leq 10^2,|x|, |y| \leq 10^2\)。

对于以上每部分数据,都有50% 的数据n 是奇数。

注意数据范围是x 和y 的绝对值,x 和y 可以是负数。

分析

题目中描述的距离就是切比雪夫距离,转化为曼哈顿距离后发现,要求的就是找一个点\((x,y)\)使得

\[\sum_{i=1}^n(|x-x_i|+|y-y_i|) \\
= \sum_{i=1}^n|x-x_i| + \sum_{i=1}^n|y-y_i|
\]

最小。

显然应该选取xi和yi的中位数。

程序实现的时候把曼哈顿距离下的点横纵坐标都乘2,方便判断小数部分是不是0.5。

但是有问题,就是选出来的在曼哈顿距离下是整点,但在切比雪夫距离下不一定是整点。

所以需要分类讨论。

  1. 能选的只有一个点,但这个点不是整点,所以要想四周抖动。
  2. 能选的是一个范围,所以要奇偶配对。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#include<cassert>
#define rg register
#define il inline
#define co const
#pragma GCC optimize ("O0")
using namespace std;
template<class T> il T read()
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return data*w;
}
template<class T> il T read(T&x)
{
return x=read<T>();
}
typedef long long ll;
const int INF=0x7fffffff; const int MAXN=1e5+7;
int n;
ll x[MAXN],y[MAXN];
ll ans,cnt; void calc(ll x,ll y)
{
ll t=0;
for(int i=0;i<n;++i)
{
t+=abs(::x[i]-x)+abs(::y[i]-y);
}
if(ans>t)
{
ans=t;
cnt=1;
}
else if(ans==t)
{
++cnt;
}
} ll odd(ll L,ll R)
{
ll t=R-L+1;
if((L&1)&&(R&1))
{
t=(t+1)/2;
}
else
{
t/=2;
}
return t;
} ll even(ll L,ll R)
{
ll t=R-L+1;
if(L%2==0&&R%2==0)
{
t=(t+1)/2;
}
else
{
t/=2;
}
return t;
} void solve(ll x1,ll x2,ll y1,ll y2)
{
if(x1==x2&&y1==y2&&(x1+y1)&1)
{
calc(x1-1,y1);
calc(x1+1,y1);
calc(x1,y1-1);
calc(x1,y1+1);
assert(ans%2==0);
}
else
{
calc(x1,y1);
cnt=odd(x1,x2)*odd(y1,y2)+even(x1,x2)*even(y1,y2);
assert(ans%2==0);
}
} int main()
{
freopen("zhengzhou.in","r",stdin);
freopen("zhengzhou.out","w",stdout);
read(n);
for(int i=0;i<n;++i)
{
ll x=read<ll>(),y=read<ll>();
::x[i]=x+y,::y[i]=x-y; // *2
}
sort(x,x+n);
sort(y,y+n);
ans=1e18;
solve(x[(n-1)/2],x[n/2],y[(n-1)/2],y[n/2]);
printf("%lld\n%lld\n",ans/2,cnt);
// fclose(stdin);
// fclose(stdout);
return 0;
}

最新文章

  1. CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)
  2. C#基础-关于用json给控制台程序传值的坑
  3. android应用内存占用测试(每隔一秒打印procrank的信息)
  4. [转]hadoop hdfs常用命令
  5. Android——关于Activity跳转的返回(无返回值和有返回值)——有返回值
  6. python之库组织
  7. 戴尔笔记本win8.1+UEFI下安装Ubuntu14.04过程记录
  8. final(最终、修饰符)
  9. 网络编程Socket之TCP之close/shutdown具体解释(续)
  10. winserver2008r2 + iis7安装django
  11. MySQL replication illegal mix of collations
  12. 【BZOJ4872】分手是祝愿(动态规划,数学期望)
  13. angular的$scope的使用
  14. 排序算法入门之选择排序-Java实现
  15. C# .NET Web API 如何自訂 ModelBinder
  16. Android 开发者必知必会的权限管理知识
  17. Linux常用命令大全(非常全!!!)(转)
  18. html/css的学习之路(2)
  19. 第三次实验计算分段函数 第四次计算分段函数和循环NEW 第五次分支+循环加强版 实验报告
  20. python-docx

热门文章

  1. SpringMVC—概述
  2. VS2010/MFC编程入门之二十(常用控件:静态文本框)
  3. 2018 Multi-University Training Contest 2 Solution
  4. bzoj1621 / P2907 [USACO08OPEN]农场周围的道路Roads Around The Farm
  5. MFC读写EXIF信息,图片非占用
  6. linux内核分析第八周-理解进程调度时机跟踪分析进程调度与进程切换的过程
  7. Python学习笔记:与Java 基础语法对比
  8. 【热更新IK词典】ElasticSearch IK 自动热更新原理与实现
  9. 初始化 Flask 虚拟环境 命令
  10. Mac adb 安装