Building A New Barn(POJ-3269)
Problem Description
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?
Input
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
Output
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.
Sample Input
4
1 -3
0 1
-2 1
1 -1
Sample Output
10 4
—————————————————————————————————————————————
題意:給出n個(gè)點(diǎn)及其坐標(biāo),求一點(diǎn)到其它點(diǎn)曼哈頓距離總和最小值以及解的個(gè)數(shù)。
思路:一開始題都讀不明白,問了隊(duì)里數(shù)學(xué)系的大佬,才發(fā)現(xiàn)是一道及其簡(jiǎn)單的中學(xué)數(shù)學(xué)題。。數(shù)學(xué)題。。。
兩點(diǎn)曼哈頓距離公式:d=|x1?x2|+|y1?y2|,由于兩點(diǎn)曼哈頓距離的特性,單獨(dú)求 x 與單獨(dú)求 y 互不影響
?
因此,題目即為求 |x?x1|+|x?x2|+…+|x?xn| 的最小值,求 |y?y1|+|y?y2|+…+|y?yn| 的最小值,直接求兩者中位數(shù)即可。
接對(duì) x、y 各自進(jìn)行排序比較:
? ? 1)當(dāng)n為奇數(shù)時(shí),取( x[n/2+1],y[n/2+1] )
若該點(diǎn)為給出點(diǎn),枚舉它的上下左右四個(gè)方向上的點(diǎn)能求的最小的 d,然后統(tǒng)計(jì)當(dāng)且僅當(dāng)這4個(gè)點(diǎn)的方案數(shù);
若該點(diǎn)不為給出點(diǎn),則直接記錄最小距離,方案數(shù)為1。
? ? 2)當(dāng)n為偶數(shù)時(shí),取( x[n/2],y[n/2] )和( x[n/2+1],y[n/2+1] )
????? ? 由曼哈頓距離的特性知:共有( x[n/2+1]?x[n/2]+1)*( y[n/2+1]?y[n/2]+1)個(gè)點(diǎn),且它們到給定的n個(gè)點(diǎn)的曼哈頓距離和d相等。
????? ? 因此枚舉每個(gè)點(diǎn)是否為給定的點(diǎn),求一次最小距離,再先讓方案數(shù)為點(diǎn)的個(gè)數(shù),每次更新減小方案數(shù)即可。
Source Program
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<string> #include<cstdlib> #include<queue> #include<set> #include<vector> #define INF 0x3f3f3f3f #define PI acos(-1.0) #define N 10001 #define MOD 123 #define E 1e-6 using namespace std; int dx[4]={0,1,0,-1}; int dy[4]={1,0,-1,0}; struct Node{int x;int y; }a[N]; int x[N],y[N]; int minn,plan; int main() {int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d%d",&a[i].x,&a[i].y);x[i]=a[i].x;y[i]=a[i].y;}sort(x+1,x+n+1);//對(duì)x排序sort(y+1,y+n+1);//對(duì)y排序if(n%2)//n為奇數(shù)時(shí){int temp=(n/2)+1;for(int i=1;i<=n;i++){if(a[i].x==x[temp]&&a[i].y==y[temp])//若點(diǎn)為給出點(diǎn){int Min=INF;for(int l=0;l<4;l++)//枚舉四個(gè)方向{int xx=x[temp]+dx[l];int yy=y[temp]+dy[l];int sum=0;for(i=1;i<=n;i++)//求最小的距離sum+=abs(a[i].x-xx)+abs(a[i].y-yy);if(sum<Min){Min=sum;plan=1;}else if (sum==Min)plan++;}printf("%d %d\n",Min,plan);return 0;}else//若點(diǎn)不為給出點(diǎn){minn+=abs(a[i].x-x[temp])+abs(a[i].y-y[temp]);//記錄最小距離plan=1;//方案數(shù)為1}}printf("%d %d\n",minn,plan);}else//n為偶數(shù)時(shí){int temp1=n/2,temp2=n/2+1;plan=(x[temp2]-x[temp1]+1)*(y[temp2]-y[temp1]+1);//令方案數(shù)等于點(diǎn)的個(gè)數(shù)for(int i=1;i<=n;i++){minn+=abs(a[i].x-x[temp1])+abs(a[i].y-y[temp1]);//記錄最小距離int x0=a[i].x,y0=a[i].y;if (x[temp1]<=x0&&x0<=x[temp2]&&y[temp1]<=y0&&y0<=y[temp2])//更新方案數(shù)plan--;}printf("%d %d\n",minn,plan);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的Building A New Barn(POJ-3269)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 爬楼梯(信息学奥赛一本通-T1204)
- 下一篇: 训练日志 2018.11.28