網教13. 平面上的郵局

在一個平面上有n(1<=n<=100000)個村莊,每個村莊通過座標(xi,yi)標示位置,-10^9<=xi,yi<=10^9。現在想要建一個郵局,使得到各個村莊的距離之和最短。
在這個問題中,距離定義爲曼哈頓距離,即點i和點j的距離等於|xi-xj|+|yi-yj|
輸入第一行爲n,表示村莊的數量
接下來n行每行有兩個整數,表示一個村莊的座標
輸出一個數字,表示建立的郵局到各個村莊的和

提示:

村莊和郵局的座標都一定爲整數

對於超過int的數字,請用long long,輸入和讀取用%lld

  測試輸入關於“測試輸入”的幫助 期待的輸出關於“期待的輸出”的幫助 時間限制關於“時間限制”的幫助 內存限制關於“內存限制”的幫助 額外進程關於“{$a} 個額外進程”的幫助
測試用例 1 以文本方式顯示
  1. 3↵
  2. 0 0↵
  3. 10 10↵
  4. 0 10↵
以文本方式顯示
  1. 20↵
無限制 64M 0
題解:
求的是曼哈頓距離,只用計算橫豎距離即可。而在兩個點(再加上xy座標)構成的矩形裏的任何一點時距離之和就是固定的。所以要找點的話就找被所有矩形都包括的點即可。而又不用找這樣的點,只用找距離,這樣就簡單許多了,也就直接把這些矩形的長和寬之和相加就行了。因爲只用求曼哈頓距離,所以分開,分別求x軸和y軸的距離就行。至於找矩形長/寬的長度,就是x軸上最左和最右的連起來,次左和次右的連起來……把這些長度都加起來就是x方向的了。y軸一樣。由此即可得到sum值。
AC代碼:
#include<stdio.h>  
#include<stdlib.h>  
#include<math.h>  
long long int x[100005], y[100005];//只能橫豎走,所以分開看就行  
int comp(const void*a, const void*b)  
{  
    return *(long long int*)a - *(long long int*)b;  
}  
int main()  
{  
    int n;  
    scanf("%d", &n);  
    int i;  
    for (i = 0; i < n; i++)  
        scanf("%lld%lld", &x[i], &y[i]);  
    qsort(x, n, sizeof(long long int), comp);  
    qsort(y, n, sizeof(long long int), comp);  
    long long sum = 0;  
    for (i = 0; i < n; i++)  
        sum += abs(x[n - 1 - i] - x[i]);  
    for (i = 0; i < n; i++)  
        sum += abs(y[n - 1 - i] - y[i]);  
    printf("%lld\n", sum/2);//sum全都加了兩遍,最後除2  
    return 0;  
}  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章