HDU 4311 前缀和

Description

It has been ten years since TJU-ACM established. And in this year all the retired TJU-ACMers want to get together to celebrate the tenth anniversary. Because the retired TJU-ACMers may live in different places around the world, it may be hard to find out where to celebrate this meeting in order to minimize the sum travel time of all the retired TJU-ACMers. 
There is an infinite integer grid at which N retired TJU-ACMers have their houses on. They decide to unite at a common meeting place, which is someone‘s house. From any given cell, only 4 adjacent cells are reachable in 1 unit of time. 
Eg: (x,y) can be reached from (x-1,y), (x+1,y), (x, y-1), (x, y+1). 
Finding a common meeting place which minimizes the sum of the travel time of all the retired TJU-ACMers.

Input

The first line is an integer T represents there are T test cases. (0<T <=10) 
For each test case, the first line is an integer n represents there are n retired TJU-ACMers. (0<n<=100000), the following n lines each contains two integers x, y coordinate of the i-th TJU-ACMer. (-10^9 <= x,y <= 10^9)

Output

For each test case, output the minimal sum of travel times.

Sample Input

4
6
-4 -1
-1 -2
2 -4
0 2
0 3
5 -2
6
0 0
2 0
-5 -2
2 -2
-1 2
4 0
5
-5 1
-1 3
3 1
3 -1
1 -1
10
-1 -1
-3 2
-4 4
5 2
5 -4
3 -1
4 3
-1 -2
3 4
-2 2

Sample Output

26
20
20
56

Hint

In the first case, the meeting point is (-1,-2); the second is (0,0), the third is (3,1) and the last is (-2,2)

题意:n人在不同的地方,选择其中一个人的屋子,使得其他人到这个地方去的距离之和最短

题解:题目要求的距离是曼哈顿距离|x1-x2|+|y1-y2|;所以可以考虑将x,y,分开计算,最后取和的max;

如何快速处理其他位置到i位置的距离dis[i]?先将坐标排个序 记录前缀和

可以发现相邻位置的两个i,j=i+1的距离和的关系

dis[j]=dis[i]+(j-2)*(sumx[j]-sumx[i])-(n-j)*(sumx[j]-sumx[i]) =dis[i]+(2*i-n)*(sumx[j]-sumx[i])

 1 /******************************
 2 code by drizzle
 3 blog: www.cnblogs.com/hsd-/
 4 ^ ^    ^ ^
 5  O      O
 6 ******************************/
 7 //#include<bits/stdc++.h>
 8 #include<iostream>
 9 #include<cstring>
10 #include<cstdio>
11 #include<map>
12 #include<algorithm>
13 #include<cmath>
14 #define ll long long
15 #define PI acos(-1.0)
16 #define mod 1000000007
17 int t;
18 using namespace std;
19 struct node
20 {
21     ll x,y,pos;
22 } N[100005];
23 ll sumx[100005];
24 ll sumy[100005];
25 ll ans1[100005];
26 ll ans2[100005];
27 int exm;
28 bool cmp1(struct node aa,struct node bb)
29 {
30     return aa.x<bb.x;
31 }
32 bool cmp2(struct node aa,struct node bb)
33 {
34     return aa.y<bb.y;
35 }
36 int main()
37 {
38     while(~scanf("%d",&t))
39     {
40         for(int i=1; i<=t; i++)
41         {
42             scanf("%d",&exm);
43             memset(N,0,sizeof(N));
44             memset(ans1,0,sizeof(ans1));
45             memset(ans2,0,sizeof(ans2));
46             for(int j=1; j<=exm; j++)
47             {
48                 scanf("%I64d %I64d",&N[j].x,&N[j].y);
49                 N[j].pos=j;
50             }
51             sort(N+1,N+1+exm,cmp1);
52             sumx[1]=0;
53             for(int j=2; j<=exm; j++)
54             {
55                 sumx[j]=sumx[j-1]+N[j].x-N[j-1].x;
56                 ans1[N[1].pos]+=sumx[j];
57             }
58             for(int j=2; j<=exm; j++)
59             {
60
61                 ans1[N[j].pos]=ans1[N[j-1].pos]-(exm-j)*(sumx[j]-sumx[j-1])+(j-2)*(sumx[j]-sumx[j-1]);
62             }
63             sort(N+1,N+1+exm,cmp2);
64             sumy[1]=0;
65             for(int j=2; j<=exm; j++)
66             {
67                 sumy[j]=sumy[j-1]+N[j].y-N[j-1].y;
68                 ans2[N[1].pos]+=sumy[j];
69             }
70             for(int j=2; j<=exm; j++)
71             {
72                 ans2[N[j].pos]=ans2[N[j-1].pos]-(exm-j)*(sumy[j]-sumy[j-1])+(j-2)*(sumy[j]-sumy[j-1]);
73             }
74             ll maxn=ans1[1]+ans2[1];
75             for(int j=1; j<=exm; j++)
76             {
77                 if(ans1[j]+ans2[j]<maxn)
78                 {
79                     maxn=ans1[j]+ans2[j];
80                 }
81             }
82             printf("%I64d\n",maxn);
83         }
84     }
85     return 0;
86 }
时间: 2024-08-28 23:11:31

HDU 4311 前缀和的相关文章

HDU 4311 Meeting point-1 &amp;&amp; HDU 4312 Meeting point-2

这俩个题  题意::给出N(<1e5)个点求找到一个点作为聚会的地方,使每个点到达这里的距离最小.4311是 曼哈顿距离 4312是 切比雪夫距离: 曼哈顿距离 :大家都知道 对于二维坐标系a(xa,yb),b(xb,yb)的曼哈顿距离是abs(xa-xb)+abs(ya-yb): 看的出来这个距离和x,y 都有关,但是X,Y并不相互影响,所以可以分开计算这样,分开计算的好处如下: 如果 只给一个维度的坐标系 ,我们是不可以再什么养的复杂度的时间内处理出来呢? 大难还是很好想的先排序一下,会发现

HDU 4311&amp;4312 Meeting point-1&amp;2 (曼哈顿距离&amp;&amp;切比雪夫距离)

HDU 4311 题意:平面上有n个点,一个点(x,y)只能到达(x-1,y), (x+1,y), (x, y-1), (x, y+1)4个点.从n个点中找到一点,使其他点到此点的距离之和最小. 思路: 可以发现,两个点间距离为 |x1-x2| + |y1-y2| ,这便是两点间的曼哈顿距离. 朴素的做法是遍历所有点,枚举该点与其他点间的曼哈顿距离之和,但是会TLE: 取巧的做法是将所有点与中心点的曼哈顿距离排序,枚举中间大概250个点左右的情况比较即可(不要欺负人家数据水! 正确姿势: 用结构

【HDU 4311】Meeting point-1(前缀和求曼哈顿距离和)

题目链接 正经解法: 给定n个点的坐标,找一个点,到其他点的曼哈顿距离之和最小.n可以是100000.大概要一个O(nlogn)的算法.算欧几里得距离可以把x和y分开计算排好序后计算前缀和就可以在O(1)时间内判断一个点到其他点的距离. #include<cstdio> #include<algorithm> using namespace std; #define ll long long #define N 100005 int t,n; ll ans,sum[N],sx[N]

hdu 5084 前缀和预处理

http://acm.hdu.edu.cn/showproblem.php?pid=5084 给出矩阵M,求M*M矩阵的r行c列的数,每个查询跟前一个查询的结果有关. 观察该矩阵得知,令ans = M*M,则 ans[x][y] = (n-1-x行的每个值)*(n-1+y列的每个值),即: ans[x][y] = t[y] * t[2*n - 2 - x] +....+ t[y + n - 1]*t[n - 1 - x] 每一对的和为定值2*n-2-x-y,然后就是求每对i+j的前缀和(所有i+

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; ManacherK - Count the string HDU - 3336(前缀数量问题)

K - Count the string HDU - 3336 题目链接:https://vjudge.net/contest/70325#problem/K 题目: It is well known that AekdyCoin is good at string problems as well as number theory problems. When given a string s, we can write down all the non-empty prefixes of t

hdu 5163(前缀和+分类讨论)

Taking Bus Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1275    Accepted Submission(s): 420 Problem Description Bestland has a very long road and there are n bus station along the road, whic

hdu 6025 前缀 后缀 gcd

大致题意: 去掉一个元素能使这个数列的GCD最大为多少 分析: 我们求一个数列的GCD,是先求前两个元素的GCD,然后将这个GCD值在与下一个元素进行GCD运算.由此可知进行GCD运算的顺序对最终的结果是没有影响的.我们再看看数列的长度范围,小于100000.那我们就枚举去掉的那个元素,那么去掉元素后的数列的GCD即这个元素前面一段数列的GCD再与这个元素后面一段数列的GCD进行GCD运算.所以我们需要两个数组分别记录前缀GCD和后缀GCD,这两个数组都可以通过O(n)算法算出来. #inclu

HDU - 6186 前缀和位运算

异或操作蒙蔽了我的双眼 以至于没有第一时间想到前缀和与后缀和 水题做的不够多 #include<bits/stdc++.h> #define rep(i,j,k) for(register int i=j;i<=k;i++) #define rrep(i,j,k) for(register int i=j;i>=k;i--) using namespace std; typedef long long ll; const int maxn = 1e5+11; ll xxor[max

!HDU 4311 最小曼哈顿距离-思维&amp;卡时间-(横纵坐标分开算,排序)

题意:有n个点,求以这n个点中的某一点为起点,到各点的曼哈顿距离和最小是多少 分析: 暴力枚举又要超时,这种题一般都是考思维了,多半都是用技巧找到一个高效的方法.个人觉得这题跟上一篇文章的题是一个类型.这种思想要记住. 这题也是用"分治",虽说题目要求的是曼哈顿距离,但是我们为什么真的就要一步到位的求呢,可以横纵坐标分开求,先x排序,然后遍历一遍,求出横坐标的距离,然后y排序,遍历一遍求出坐标的距离加在刚才求得的x的距离上,就是曼哈顿距离了. 这里有一个非常巧妙但是其实很显而易见的东西