1. 程式人生 > >BZOJ1696: [Usaco2007 Feb]Building A New Barn新牛舍

BZOJ1696: [Usaco2007 Feb]Building A New Barn新牛舍

-- struct [] play 找到 %d operator ans inf

n<=10000個點(xi,yi),找到一個不同於給出的所有點的點,使得該點到所有點的曼哈頓距離最小並找出這樣的點的個數。

第一眼看上去這不是中位數嘛,奇數一個點偶數一片,然後找一下這篇區域有幾個不符合的點即可。不過要找出“不同於給出的點”的點,那萬一中位數那個點被占了,就找它四周四個點即可。

錯誤!明知道會有中位數那一個點被占了,那怎麽就不考慮四周都被占了的情況?

不過可以肯定的是,離中位數越近的點算出來的距離是越小的,盡管與中位數點距離相同的點答案可能不同。因此判斷下中位數區域是否大於n,如果是那直接記答案(因為該區域肯定有答案),否則bfs。

為什麽判重要用map呢其實用set就好了。。。。

技術分享
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5 #include<map>
  6 //#include<iostream>
  7 using namespace std;
  8 
  9 int n;
 10 #define maxn 40011
 11 int x[maxn],y[maxn],sx[maxn],sy[maxn];
 12 struct Point
 13 {
 14
int x,y; 15 bool operator < (const Point &b) const 16 {return x<b.x || (x==b.x && y<b.y);} 17 }p[maxn]; 18 map <Point,bool> mp,vis; 19 int ans,cnt; 20 struct qnode{int d,x,y;}q[maxn];int head,tail; 21 const int dx[]={0,0,0,1,-1},dy[]={0,1,-1,0,0},inf=0x3f3f3f3f
; 22 int dis(int xx,int yy) 23 { 24 int L=0,R=n+1; 25 while (L<R) 26 { 27 const int mid=(L+R+1)>>1; 28 if (x[mid]<xx) L=mid; 29 else R=mid-1; 30 } 31 int idx=L; 32 L=0;R=n+1; 33 while (L<R) 34 { 35 const int mid=(L+R+1)>>1; 36 if (y[mid]<yy) L=mid; 37 else R=mid-1; 38 } 39 int idy=L; 40 return (2*idx-n)*xx-2*sx[idx]+sx[n]+(2*idy-n)*yy-2*sy[idy]+sy[n]; 41 } 42 bool bfs(int d) 43 { 44 bool flag=0; 45 while (head!=tail && q[head].d==d) 46 { 47 const int nx=q[head].x,ny=q[head++].y; 48 if (head==maxn) head=0; 49 if (!mp.count((Point){nx,ny})) 50 { 51 flag=1;int tmp=dis(nx,ny); 52 if (ans>tmp) 53 { 54 ans=tmp; 55 cnt=1; 56 } 57 else if (ans==tmp) cnt++; 58 } 59 else 60 { 61 for (int i=1;i<=4;i++) 62 { 63 const int px=nx+dx[i],py=ny+dy[i]; 64 if (vis.count((Point){px,py})) continue; 65 vis[(Point){px,py}]=1; 66 qnode &now=q[tail]; 67 now.x=px;now.y=py;now.d=d+1;tail++; 68 } 69 } 70 } 71 return flag; 72 } 73 int main() 74 { 75 scanf("%d",&n); 76 for (int i=1;i<=n;i++) 77 { 78 scanf("%d%d",&x[i],&y[i]); 79 p[i].x=x[i];p[i].y=y[i]; 80 mp[(Point){x[i],y[i]}]=1; 81 } 82 sort(x+1,x+1+n);sort(y+1,y+1+n); 83 sx[0]=0;for (int i=1;i<=n;i++) sx[i]=sx[i-1]+x[i]; 84 sy[0]=0;for (int i=1;i<=n;i++) sy[i]=sy[i-1]+y[i]; 85 int x1=x[(n+1)/2],x2=x[n/2+1],y1=y[(n+1)/2],y2=y[n/2+1]; 86 if (1ll*(x2-x1+1)*(y2-y1+1)>n) 87 { 88 ans=sx[n]-2*sx[(n+1)/2]+sy[n]-2*sy[(n+1)/2];cnt=1ll*(x2-x1+1)*(y2-y1+1); 89 for (int i=1;i<=n;i++) 90 if (p[i].x>=x1 && p[i].x<=x2 && p[i].y>=y1 && p[i].y<=y2) cnt--; 91 printf("%d %d\n",ans,cnt); 92 } 93 else 94 { 95 head=tail=0;ans=inf; 96 for (int i=x1;i<=x2;i++) 97 for (int j=y1;j<=y2;j++) 98 { 99 qnode &now=q[tail]; 100 now.x=i;now.y=j;now.d=0;tail++; 101 vis[(Point){i,j}]=1; 102 } 103 x[0]=y[0]=-inf;x[n+1]=y[n+1]=inf; 104 int play=0; 105 while (!bfs(play++)); 106 printf("%d %d\n",ans,cnt); 107 } 108 return 0; 109 }
View Code

BZOJ1696: [Usaco2007 Feb]Building A New Barn新牛舍