题解 P2874 【[USACO07FEB]新牛棚Building A New Barn】
思路:
首先,我们知道两点曼哈顿距离公式:
设
那么有
容易发现,
这样本题就变成了一道中学数学题:求
由中学的数学知识可知直接求中位数就行了(可以分类讨论,也可以几何意义解决)。
那么,我们直接对
1、当
若该点为给出的点,则枚举它的上下左右四个点上能求得的最小的
若该点不为给出的点,则直接将
2、当
欢迎来踩博客:five20(本人蒟蒻,写题不易,转载请注明出处)
代码:
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define debug printf("%d %s\n",__LINE__,__FUNCTION__)
using namespace std;
const int N=1e5+7;
int n,b[N],c[N],ans1=233333333,ans2;
struct point{int x,y;}a[N];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
il int gi(){
int a=0;char x=getchar();bool f=0;
while((x<'0'||x>'9')&&x!='-')x=getchar();
if(x=='-')x=getchar(),f=1;
while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
return f?-a:a;
}
il int getsum(int x,int y){
int ans=0;
for(int i=1;i<=n;i++)ans+=abs(x-b[i])+abs(y-c[i]);
return ans;
}
int main()
{
n=gi();
for(int i=1;i<=n;i++)a[i].x=b[i]=gi(),a[i].y=c[i]=gi();
sort(b+1,b+n+1);
sort(c+1,c+n+1);
if(n&1){
int x=b[(n>>1)+1],y=c[(n>>1)+1];
for(int i=0;i<4;i++){
int xx=x+dx[i],yy=y+dy[i];
int sum=getsum(xx,yy);
if(sum<ans1)ans1=sum,ans2=1;
else if(sum==ans1)++ans2;
}
}
else {
int x1=b[(n>>1)+1],x2=b[n>>1],y1=c[(n>>1)+1],y2=c[n>>1];
ans2=(x1-x2+1)*(y1-y2+1);
ans1=getsum(x1,y1);
for(int i=1;i<=n;i++)
if(a[i].x>=x2&&a[i].x<=x1&&a[i].y>=y2&&a[i].y<=y1)ans2--;
}
cout<<ans1<<' '<<ans2;
return 0;
}