PIPIOJ 1018: Soldiers line up greedy mathematics

http://pipioj.online/problem.php?id=1018
Insert picture description here
Idea: Very similar to this question . Since it is known that when x = a [mid] x=a[mid]x=a[mid]时, ∑ i = 1 n ∣ a i − x ∣ \sum_{i=1}^n|a_i-x| i=1naix ∣ takes the minimum value, then the ordinate of moving all soldiers to the same row is determined. Now consider the abscissa, assuming that the abscissa of the first soldier in the final result isttt , then according to the greedy strategy, we must hope that the smallestxi x_ixiMove to ttt , the second smallestxi x_ixiMove to t + 1 t+1t+1 ……Then after sorting the abscissa, we hope to find:
min (∑ i = 1 n ∣ xi − (t + i − 1) ∣) = min (∑ i = 1 n ∣ (xi − i + 1 ) − T ∣) min(\sum_{i=1}^n|x_i-(t+i-1)|)=min(\sum_{i=1}^n|(x_i-i+1)-t |)m i n (i=1nxi(t+i1))=m i n (i=1n(xii+1)t)
x i ′ = x i − i + 1 x_i'=x_i-i+1 xi=xii+1 , the above equation can be changed:min (∑ i = 1 n ∣ xi ′ − t ∣) min (\ sum_ {i = 1} ^ n | x_i'-t |)m i n ( i=1nxit ) , obviously whent = x ′ [mid] t=x'[mid]t=x [Mid]is the minimum value.

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

const int maxn=1e4+5;

int n,x[maxn],y[maxn];

int main()
{
    
    
    while(~scanf("%d",&n))
    {
    
    
        for(int i=1;i<=n;i++)
            scanf("%d %d",&x[i],&y[i]);
        sort(x+1,x+1+n);
        for(int i=1;i<=n;i++)
            x[i]-=i-1;
        sort(x+1,x+1+n);
        sort(y+1,y+1+n);
        int xmid=x[(n+1)>>1];
        int ymid=y[(n+1)>>1];
        int cnt=0;
        for(int i=1;i<=n;i++)
            cnt+=abs(x[i]-xmid)+abs(y[i]-ymid);
        printf("%d\n",cnt);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/xiji333/article/details/114424413