[USACO07FEB]新牛棚Building A New Barn


# 洛谷題目鏈接:[[USACO07FEB]新牛棚Building A New Barn](https://www.luogu.org/problemnew/show/P2874)

題目描述

After scrimping and saving for years, Farmer John has decided to build a new barn. He wants the barn to be highly accessible, and he knows the coordinates of the grazing spots of all N (2 ≤ N ≤ 10,000 cows. Each grazing spot is at a point with integer coordinates (Xi, Yi) (-10,000 ≤ Xi ≤ 10,000; -10,000 ≤ Yi ≤ 10,000). The hungry cows never graze in spots that are horizontally or vertically adjacent.

The barn must be placed at integer coordinates and cannot be on any cow's grazing spot. The inconvenience of the barn for any cow is given the Manhattan distance formula | X - Xi | + | Y - Yi|, where (X, Y) and (Xi, Yi) are the coordinates of the barn and the cow's grazing spot, respectively. Where should the barn be constructed in order to minimize the sum of its inconvenience for all the cows?
給出平面上n個不相鄰的點,要求到這n個點的曼哈頓距離之和最小的點的個數ans2,和這個最小距離ans1。

輸入輸出格式

輸入格式:

Line 1: A single integer: N

Lines 2..N+1: Line i+1 contains two space-separated integers which are the grazing location (Xi, Yi) of cow i

輸出格式:

Line 1: Two space-separated integers: the minimum inconvenience for the barn and the number of spots on which Farmer John can build the barn to achieve this minimum.

輸入輸出樣例

輸入樣例#1:

4
1 -3
0 1
-2 1
1 -1

輸出樣例#1:

10 4

說明

The minimum inconvenience is 10, and there are 4 spots that Farmer John can build the farm to achieve this: (0, -1), (0, 0), (1, 0), and (1, 1).

簡述一下題意:給出一個二維平面上\(n\)個點.要求出\(ans2\)個點使得這\(ans2\)個點到所有點的曼哈頓距離之和,這\(ans2\)個點不能是原平面直角坐標系中給出的點.兩點間曼哈頓距離的公式為\(\left|x-x_i\right|+\left|y-y_i\right|\).

既然要到所有點的曼哈頓距離之和最小,那么可以先設答案點坐標為\((x,y)\).可以得到這樣一個式子:

\[ans1=\sum{(\left|x-x_i\right|+\left|y-y_i\right|)} \]

顯然我們是要求出一個\((x,y)\)使得\(ans1\)最小,因為\(x\),\(y\)互不影響,所以可以分開處理,那么根據我們的數學知識,可以得知使\(ans1\)最小的值就是\(x\)序列的中位數,同理\(y\)也是序列中的中位數.

這樣我們就求出了\(ans1\),但是因為題目的限制,如果\(n\)為奇數時,\(x\)\(y\)直接求出的中位數有可能是原圖中給出的點.所以這時我們要對這個點的上下左右進行判斷,對上下左右求一遍最小值.

如果\(n\)為偶數時,那么在\(x[n/2],x[n/2+1],y[n/2],y[n/2+1]\)這四個點所圍成的矩形中的所有點都是滿足條件的. 先計算出這個矩形中包含的點的個數,然后再將原圖中包含的點都一個個刪掉.

#include<bits/stdc++.h>
using namespace std;
const int inf=2147483647;
const int N=10000+5;

int n, x[N], y[N], ans1 = inf, ans2 = 0;
int dir[]={0,1,0,-1,0};

struct node{
    int x, y;
}p[N];

int gi(){
    int ans = 0 , f = 1; char i = getchar();
    while(i<'0'||i>'9'){if(i=='-')f=-1;i=getchar();}
    while(i>='0'&&i<='9'){ans=ans*10+i-'0';i=getchar();}
    return ans * f;
}

int main(){
    cin >> n;
    for(int i=1;i<=n;i++) x[i] = gi(), y[i] = gi();
    for(int i=1;i<=n;i++) p[i].x = x[i], p[i].y = y[i];
    sort(x+1 , x+n+1); sort(y+1 , y+n+1);
    if(n & 1){
		int a = x[n/2+1], b = y[n/2+1], sum = 0;
		for(int i=1;i<=n;i++)
		    sum += abs(a-x[i])+abs(b-y[i]);
		ans1 = sum; ans2 = 1;
		for(int i=1;i<=n;i++)
		    if(p[i].x == a && p[i].y == b) ans1 = inf;
		for(int i=0;i<4;i++){
		    int nx = a+dir[i], ny = b+dir[i+1], sum = 0;
		    for(int i=1;i<=n;i++)
			sum += abs(nx-x[i])+abs(ny-y[i]);
		    if(sum < ans1) ans1 = sum, ans2 = 1;
		    else if(sum == ans1) ans2++;
		}
	}
    else{
		int x1 = x[n/2], x2 = x[n/2+1];
		int y1 = y[n/2], y2 = y[n/2+1], sum = 0;
		for(int i=1;i<=n;i++)
		    sum += abs(x1-x[i])+abs(y1-y[i]);
		ans1 = min(ans1 , sum);
		ans2 = (x2-x1+1)*(y2-y1+1);
		for(int i=1;i<=n;i++)
		    if(x1<=p[i].x && p[i].x<=x2 && y1<=p[i].y && p[i].y<=y2) ans2--;
    }
    printf("%d %d\n",ans1,ans2);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM