POJ_1723_SOLDIERS

//水平与垂直互不影响,这是关键。 //对于中位数使y方向目标最小,可以这么理解,例如y1,y2(有序),要使|y-y1|+|y-y2|最小,y必须y2>=y>=y1 //同理y3,y1,y2,y4,|y-y3|+|y-y4|最小,y3<=y<=y4,而要|y-y1|+|y-y2|+|y-y3|+|y-y4|最小,必须使y取到两个 //区间重叠的部分,以上是y值为偶数的情况,对于为奇数的情况,可以将中间值看为一个区间。 /*下面从网上搜到的,感觉不难理解: 现在确定好了Y,我们来考虑如何确定X。感觉上水平和垂直两个方向既然分离了,就应该有某种联系。 我们不妨将x[]变换后的状态记为x′[], 则x′[i] = X + i – 1,反解出X = x′[i] – (i – 1)。到这里我们发现,果然存在一个函数F使 得x′[]中的元素相关到一个恒定量X,这就跟求Y的问题一样了。同时,x[]排序后变换到x′[],先 后次序必然不改变,否则将导致解更差。这样问题就解决了。 */ #include<stdio.h> #include<math.h> #include<algorithm> using namespace std; int x[10005],y[10005]; int n; int cmp(const void* _a,const void* _b) { int* a=(int *)_a; int* b=(int *)_b; return *a-*b; } int main() { while(scanf("%d",&n)==1) { int i,sum=0,temp[10005]; for(i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]); qsort(y,n,sizeof(y[1]),cmp); for(i=0;i<n;i++) sum+=abs(y[n/2]-y[i]); qsort(x,n,sizeof(x[1]),cmp); for(i=0;i<n;i++) temp[i]=x[i]-i; qsort(temp,n,sizeof(temp[1]),cmp); for(i=0;i<n;i++) sum+=abs(temp[i]-temp[n/2]); printf("%d/n",sum); } return 0; }

你可能感兴趣的:(ini)