BZOJ.3170.[TJOI2013]松鼠聚会(切比雪夫距离转曼哈顿距离)
将原坐标系每个点的坐标\((x,y)\)变为\((x+y,x-y)\),则原坐标系中的曼哈顿距离等于新坐标系中的切比雪夫距离。
反过来,将原坐标系每个点的坐标\((x,y)\)变为\((\frac{x+y}{2},\frac{x-y}{2})\),则原坐标系中的切比雪夫距离等于新坐标系中的曼哈顿距离。
随便写两个点就可以验证这是对的。
将题目中每个点的坐标\((x,y)\)改为\((\frac{x+y}{2},\frac{x-y}{2})\),然后记\(dis(a,b)=\Delta X+\Delta Y\)表示两个点\(a,b\)间的曼哈顿距离。
枚举每一个点\(x\),则到\(x\)的距离之和为\(Sum=\sum_{i=1}^ndis(i,x)\)。
把\(dis(i,x)\)拆开,即$$\begin{aligned}Sum&=\sum_{i=1}^n\Delta X(i,x)+\Delta Y(i,x)\&=\Delta X(1,x)+\Delta X(2,x)+...+\Delta Y(1,x)+\Delta Y(2,x)...\end{aligned}$$
把每个点按\(x\)或\(y\)排序,枚举点时就可以\(O(1)\)计算\(\Delta X\)或\(\Delta Y\)的变化量了。
当然没必要先把坐标\(x,y\)除以\(2\)。最后把答案除以\(2\)即可。
我否认在刷水题的事实。
//3072kb 264ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5;
LL Ans[N];
char IN[MAXIN],*SS=IN,*TT=IN;
struct Point
{
int x,y,id;
Point(int tid=0,int ty=0,int tx=0) {id=tid, x=tx+ty, y=tx-ty;}
}p[N];
inline int read()
{
int now=0,f=1;register char c=gc();
for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now*f;
}
bool cmpx(Point a,Point b)
{
return a.x<b.x;
}
bool cmpy(Point a,Point b)
{
return a.y<b.y;
}
int main()
{
int n=read();
for(int i=1; i<=n; ++i) p[i]=Point(i,read(),read());
std::sort(p+1,p+1+n,cmpx);
LL sum=-1ll*(n-1)*p[1].x;
for(int i=2; i<=n; ++i) sum+=p[i].x;
for(int i=1; i<=n; ++i)
Ans[p[i].id]+=sum, sum+=(2ll*i-n)*(p[i+1].x-p[i].x);//i*dx-(n-i)*dx
std::sort(p+1,p+1+n,cmpy);
sum=-1ll*(n-1)*p[1].y;
for(int i=2; i<=n; ++i) sum+=p[i].y;
for(int i=1; i<=n; ++i)
Ans[p[i].id]+=sum, sum+=(2ll*i-n)*(p[i+1].y-p[i].y);
LL ans=1e18;
for(int i=1; i<=n; ++i) ans=std::min(ans,Ans[i]);
printf("%lld\n",ans>>1);
return 0;
}
BZOJ.3170.[TJOI2013]松鼠聚会(切比雪夫距离转曼哈顿距离)的更多相关文章
- BZOJ 3170 [Tjoi2013]松鼠聚会
题解:切比雪夫距离转化为曼哈顿距离 枚举源点,横纵坐标互不影响,分开考虑,前缀和优化 横纵分开考虑是一种解题思路 #include<iostream> #include<cstdio ...
- BZOJ - 3170: 松鼠聚会 (切比雪夫转曼哈顿距离)
pro: 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离.0&l ...
- BZOJ3170: [Tjoi2013]松鼠聚会(切比雪夫距离转曼哈顿距离)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1524 Solved: 803[Submit][Status][Discuss] Descripti ...
- BZOJ3170 [Tjoi2013]松鼠聚会 切比雪夫距离 - 曼哈顿距离 - 前缀和
BZOJ3170 题意: 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最 ...
- Bzoj3170: [Tjoi2013]松鼠聚会 (切比雪夫距离)
题目链接 显然,题目要求我们求切比雪夫距离,不会的可以去看一下attack的博客. 考虑枚举所有的点 转换为曼哈顿距离后. 那么对于这个点的路程和是. \[\sum_{i=1}^n | x_i - x ...
- 3170: [Tjoi2013]松鼠聚会
Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1804 Solved: 968[Submit][Status][Discuss] Descript ...
- 【bzoj3170】[Tjoi2013]松鼠聚会
3170: [Tjoi2013]松鼠聚会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1670 Solved: 885[Submit][Statu ...
- BZOJ 3170 松鼠聚会(切比雪夫距离转曼哈顿距离)
题意 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 思路 题目 ...
- BZOJ_3170_[Tjoi2013]松鼠聚会_切比雪夫距离+前缀和
BZOJ_3170_[Tjoi2013]松鼠聚会_切比雪夫距离+前缀和 题意:有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点, ...
随机推荐
- laravel 资源控制器
Artisan 生成器来生成一个资源控制器(在之前命名后加上 --resource 选项) php artisan make:controller PostController --resource ...
- springboot集成druid+mybatis连接oracle数据库
2.1.配置 druid 数据源 2. 随后要进行druid 的数据源的配置,如果要想使用druid 的数据源,那么首先一定要去修改 pom.xml 配置文件,引入以下包: oracle官网下载 oj ...
- Python 读写excel类
#-*- coding: utf8 -*- import xlrd import xlwt from Public import GlobalClass def openexcel(path): tr ...
- 静态属性property
静态属性property(是通过对象去使用) property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 1 . 通过@property修饰过的函数属性,调用的时候无需在加() cla ...
- UPC 6616 Small Mulitple
D - Small Multiple 题目传送门 Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem Stateme ...
- Http系列笔记
万能的HttpClient (Framework与NetCore 都支持) string url = "http://localhost:5000/api/values"; //p ...
- C++ 成员初始化列表
1.什么是成员初始化列表 #include<iostream> #include<string> using namespace std; class Weapon { pri ...
- BZOJ4675
题解: 考虑这么一件事情,n个人买彩票,在不断抽走卡片的时候,他们的中奖概率是不变的 所以在这道题中,由于每个人的操作次数是确定的,所以选每k个点的概率是相同的(因为如果我们逐一考虑每一次操作这个问题 ...
- python生成随机日期字符串
python生成随机日期字符串 生成随机的日期字符串,用于插入数据库. 通过时间元组设定一个时间段,开始和结尾时间转换成时间戳. 时间戳中随机取一个,再生成时间元组,再把时间元组格式化输出为字符串 # ...
- Python题目练习(二)
1.如何实现对python列表去重,并保持原来顺序 li = [1,2,5,3,1,6,3,8,0,3,2,4] l = [] for i in li: if i not in l: l.append ...