bzoj 3170: [Tjoi 2013]松鼠聚会
2017-10-16 06:25
337 查看
3170: [Tjoi 2013]松鼠聚会
Description
有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。
Input
第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5
下面N行,每行给出x,y表示其家的坐标。
-10^9<=x,y<=10^9
Output
表示为了聚会走的路程和最小为多少。
Sample Input
6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
Sample Output
20
HINT
Source
题解:
设一只松鼠坐标为(x1,y1),另一只坐标为(x2,y2),则其中一只到另一只的距离是max(|x1-x2|,|y1-y2|)。
这其实是切比雪夫距离,但是直接用它不好做,我们可以将其转化为曼哈顿距离。
转化如下:
如果|x1-x2|>|y1-y2|,dis=|x1-x2|,否则dis=|y1-y2|。
我们可以将其转化为dis=|(x1-x2)/2+(y1-y2)/2|+|(x1-x2)/2-(y1-y2)/2|。
与上面的式子是等价的。
dis=1/2*(|(x1+y1)-(x2+y2)|+|(x1-y1)-(x2-y2)|)
因此,我们只需要对每一个坐标,记录a=(x+y),b=(x-y),求其差的前缀和即可。
附上代码:
Description
有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1。现在N个松鼠要走到一个松鼠家去,求走过的最短距离。
Input
第一行给出数字N,表示有多少只小松鼠。0<=N<=10^5
下面N行,每行给出x,y表示其家的坐标。
-10^9<=x,y<=10^9
Output
表示为了聚会走的路程和最小为多少。
Sample Input
6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
Sample Output
20
HINT
Source
题解:
设一只松鼠坐标为(x1,y1),另一只坐标为(x2,y2),则其中一只到另一只的距离是max(|x1-x2|,|y1-y2|)。
这其实是切比雪夫距离,但是直接用它不好做,我们可以将其转化为曼哈顿距离。
转化如下:
如果|x1-x2|>|y1-y2|,dis=|x1-x2|,否则dis=|y1-y2|。
我们可以将其转化为dis=|(x1-x2)/2+(y1-y2)/2|+|(x1-x2)/2-(y1-y2)/2|。
与上面的式子是等价的。
dis=1/2*(|(x1+y1)-(x2+y2)|+|(x1-y1)-(x2-y2)|)
因此,我们只需要对每一个坐标,记录a=(x+y),b=(x-y),求其差的前缀和即可。
附上代码:
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; #define int long long #define mmin(a,b) (a<b?a:b) struct tree{ int xx,yy,id; }q[101000]; int prex[100100],nxtx[1001000],prey[100100],nxty[100100],n,ans=10000000000000000ll; bool cmp1(const tree s1,const tree s2) { return s1.xx<s2.xx; } bool cmp2(const tree s1,const tree s2) { return s1.yy<s2.yy; } signed main() { // freopen("in.txt","r",stdin); scanf("%lld",&n); for(int i=1;i<=n;i++) { int x,y; scanf("%lld%lld",&x,&y); q[i].xx=x+y; q[i].yy=x-y 4000 ; q[i].id=i; } sort(q+1,q+n+1,cmp1); for(int i=1;i<=n;i++) prex[q[i].id]=prex[q[i-1].id]+(q[i].xx-q[i-1].xx)*(i-1); for(int i=n;i>=1;i--) nxtx[q[i].id]=nxtx[q[i+1].id]+(q[i+1].xx-q[i].xx)*(n-i); sort(q+1,q+n+1,cmp2); for(int i=1;i<=n;i++) prey[q[i].id]=prey[q[i-1].id]+(q[i].yy-q[i-1].yy)*(i-1); for(int i=n;i>=1;i--) nxty[q[i].id]=nxty[q[i+1].id]+(q[i+1].yy-q[i].yy)*(n-i); for(int i=1;i<=n;i++) ans=mmin(ans,prex[i]+nxtx[i]+prey[i]+nxty[i]); ans/=2; printf("%lld",ans); return 0; }
相关文章推荐
- BZOJ 3170 [Tjoi 2013]松鼠聚会 切比雪夫距离-->曼哈顿距离
- bzoj3170 [Tjoi2013]松鼠聚会(转换坐标系)
- 【bzoj3170】[Tjoi 2013]松鼠聚会
- 【TJOI2013 Day1合集】BZOJ3170 松鼠聚会 BZOJ3171 循环格 BZOJ3172 单词
- BZOJ 3170([Tjoi 2013]松鼠聚会-Manhattan距离单点最近)
- bzoj 3170: [Tjoi 2013]松鼠聚会&3210: 花神的浇花集会
- BZOJ 3170: [Tjoi 2013]松鼠聚会( sort )
- BZOJ3170: [Tjoi 2013]松鼠聚会
- BZOJ3170[TJOI2013]松鼠聚会
- bzoj3170【TJOI2013】松鼠聚会
- BZOJ3170: [Tjoi 2013]松鼠聚会
- BZOJ 3170 TJOI 2013 松鼠聚会 切比雪夫距离
- BZOJ 3170 Tjoi 2013 松鼠聚会 计算几何
- BZOJ 3170([Tjoi 2013]松鼠聚会-Manhattan距离单点最近)
- BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离
- bzoj 3170 Tjoi 2013 松鼠聚会 曼哈顿距离&&切比雪夫距离
- 【BZOJ3170】[Tjoi 2013]松鼠聚会 旋转坐标系
- 【bzoj3170】[Tjoi 2013]松鼠聚会 旋转坐标系
- bzoj-3170 3170: [Tjoi 2013]松鼠聚会(计算几何)
- [BZOJ 3170][Tjoi 2013]松鼠聚会