poj 1723 Soldiers【中位数】By cellur925

题目传送门

题目大意:平面上有n个士兵,给出每个士兵的坐标,求出使这些士兵站好所需要的最少移动步数。站好要求:所有士兵y相等,x相邻。即达到 (x,y), (x+1, y), (x+2,y)……的状态。(每行不相邻)

$Sol$

我们很容易能想到,让所有士兵y相等就要把他们都移动到所有士兵y的中位数上。这时可能存在有士兵重合在同一格点的情况。后来x轴的情况:

x轴时,先进行一次排序后,假设水平线上的n个点存储在数组a[n]中,则第一个点a[0]最终排序后的位置是addr,a[1]的最终位置是(addr+1),a[2]的最终位置是(addr+2)……a[n]------->(addr+n)。分析则有:addr = a[0]-0 = a[1]-1 = a[2]-2 = ... = a[i]-i  = ... = a[n]-n。故可将(a[i]-i)视为一个新的point,并将n各新的point移动到同一个位置addr。可以看出,将x轴的问题转化为了和y轴相同的问题。最后得出最少步数。 --------------------- 本文来自 crev 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/wutong_v/article/details/51603946?utm_source=copy 

也就是说,各个士兵在行上的相对位置是没有变的。

$Code$

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 
 6 int n,sta,ans;
 7 struct node{
 8     int x,y;
 9 }p[20000];
10 
11 bool cmp(node a,node b)
12 {
13     return a.y<b.y;
14 }
15 
16 bool cmp2(node a,node b)
17 {
18     return a.x<b.x; 
19 }
20 
21 int main()
22 {
23     scanf("%d",&n);
24     for(int i=1;i<=n;i++)
25         scanf("%d%d",&p[i].x,&p[i].y);
26     sort(p+1,p+1+n,cmp);
27     sta=p[(n+1)>>1].y;
28     for(int i=1;i<=n;i++)
29         ans+=abs(sta-p[i].y);
30         
31     sort(p+1,p+1+n,cmp2);
32     for(int i=1;i<=n;i++) p[i].x-=i;
33     sort(p+1,p+1+n,cmp2);
34     sta=p[(n+1)>>1].x;
35     for(int i=1;i<=n;i++)
36         ans+=abs(sta-p[i].x);
37     printf("%d",ans);
38     return 0;
39 }
View Code
原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9741537.html