bzoj1696[Usaco2007 Feb]Building A New Barn新牛舍*

bzoj1696[Usaco2007 Feb]Building A New Barn新牛舍

题意:

n头牛在不同坐标处吃草,没有牛相邻。求一个没有牛的点到所有点曼哈顿距离和最小和这样点的个数。n≤10000

题解:

先求x坐标的中位数区间,再求y坐标的中位数区间,如果n为偶数,答案为这个二维区间点数-落在这个区间里的牛数。n为奇数,且这个中位数点有牛的话,就在这个点的上下左右调整,然后找距离和最小的点和这样点的个数。情况比较多,容易WA。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 10100
 6 using namespace std;
 7 
 8 inline int read(){
 9     char ch=getchar(); int f=1,x=0;
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
11     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
12     return f*x;
13 }
14 struct p{int x,y;}; p ps[maxn]; int lx,rx,ly,ry,n,tot,ans;
15 bool cmp1(p a,p b){return a.x<b.x;}
16 bool cmp2(p a,p b){return a.y<b.y;}
17 int main(){
18     n=read(); inc(i,1,n)ps[i].x=read(),ps[i].y=read();
19     sort(ps+1,ps+n+1,cmp1);
20     if(n&1)lx=rx=ps[(n>>1)+1].x;else lx=ps[n>>1].x,rx=ps[(n>>1)+1].x;
21     sort(ps+1,ps+n+1,cmp2);
22     if(n&1)ly=ry=ps[(n>>1)+1].y;else ly=ps[n>>1].y,ry=ps[(n>>1)+1].y;
23     tot=(rx-lx+1)*(ry-ly+1); inc(i,1,n)if(ps[i].x>=lx&&ps[i].x<=rx&&ps[i].y>=ly&&ps[i].y<=ry)tot--;
24     if(!tot){
25         int a[4]={0,0,0,0}; tot=0; ans=0x3fffffff;
26         lx++; inc(i,1,n)a[0]+=abs(lx-ps[i].x)+abs(ly-ps[i].y); ans=min(a[0],ans); lx--;
27         lx--; inc(i,1,n)a[1]+=abs(lx-ps[i].x)+abs(ly-ps[i].y); ans=min(a[1],ans); lx++;
28         ly++; inc(i,1,n)a[2]+=abs(lx-ps[i].x)+abs(ly-ps[i].y); ans=min(a[2],ans); ly--;
29         ly--; inc(i,1,n)a[3]+=abs(lx-ps[i].x)+abs(ly-ps[i].y); ans=min(a[3],ans); ly++;
30         inc(i,0,3)if(ans==a[i])tot++;
31     }else{inc(i,1,n)ans+=abs(lx-ps[i].x)+abs(ly-ps[i].y);}
32     printf("%d %d",ans,tot); return 0;
33 }

20160809

原文地址:https://www.cnblogs.com/YuanZiming/p/5767447.html