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