BZOJ3046 : lagoon

Claris發表於2014-11-01

碼農題,拆點BFS預處理出所有聯通塊的面積即可,注意分類討論。

 

#include<cstdio>
#include<cmath>
using namespace std;
const double pi=acos(-1.0)/4.0;
const int N=210;
struct P{int x,y,z;P(){}P(int _x,int _y,int _z){x=_x,y=_y,z=_z;}}q[N*N*2],p;
int n,m,T,i,j,h,t,pos,c[N*N][3],v[N][N][3],a[N][N];char s[N];double sum[N*N],ans;
void add(int x,int y,int z){
  if(!x||!y||x>n||y>m||v[x][y][z])return;
  v[x][y][z]=pos;
  c[pos][z]++;
  q[++t]=P(x,y,z);
}
void bfs(int x,int y,int z){
  h=1,t=0,add(x,y,z);
  while(h<=t){
    p=q[h++];
    if(!p.z){
      x=p.x-1,y=p.y;
      if(!a[x][y])add(x,y,0);
      if(a[x][y]==3||a[x][y]==4)add(x,y,1);
      if(a[x][y]==1||a[x][y]==2)add(x,y,2);
      x=p.x+1,y=p.y;
      if(!a[x][y])add(x,y,0);
      if(a[x][y]==1||a[x][y]==2)add(x,y,1);
      if(a[x][y]==3||a[x][y]==4)add(x,y,2);
      x=p.x,y=p.y-1;
      if(!a[x][y])add(x,y,0);
      if(a[x][y]==2||a[x][y]==3)add(x,y,1);
      if(a[x][y]==1||a[x][y]==4)add(x,y,2);
      x=p.x,y=p.y+1;
      if(!a[x][y])add(x,y,0);
      if(a[x][y]==1||a[x][y]==4)add(x,y,1);
      if(a[x][y]==2||a[x][y]==3)add(x,y,2);
    }
    if(p.z==1){
      if(a[p.x][p.y]==1){
        x=p.x-1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==3||a[x][y]==4)add(x,y,1);
        if(a[x][y]==1||a[x][y]==2)add(x,y,2);
        x=p.x,y=p.y-1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==2||a[x][y]==3)add(x,y,1);
        if(a[x][y]==1||a[x][y]==4)add(x,y,2);
      }
      if(a[p.x][p.y]==2){
        x=p.x-1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==3||a[x][y]==4)add(x,y,1);
        if(a[x][y]==1||a[x][y]==2)add(x,y,2);
        x=p.x,y=p.y+1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==4)add(x,y,1);
        if(a[x][y]==2||a[x][y]==3)add(x,y,2);
      }
      if(a[p.x][p.y]==3){
        x=p.x+1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==2)add(x,y,1);
        if(a[x][y]==3||a[x][y]==4)add(x,y,2);
        x=p.x,y=p.y+1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==4)add(x,y,1);
        if(a[x][y]==2||a[x][y]==3)add(x,y,2);
      }
      if(a[p.x][p.y]==4){
        x=p.x+1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==2)add(x,y,1);
        if(a[x][y]==3||a[x][y]==4)add(x,y,2);
        x=p.x,y=p.y-1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==2||a[x][y]==3)add(x,y,1);
        if(a[x][y]==1||a[x][y]==4)add(x,y,2);
      }
    }
    if(p.z==2){
      if(a[p.x][p.y]==1){
        x=p.x+1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==2)add(x,y,1);
        if(a[x][y]==3||a[x][y]==4)add(x,y,2);
        x=p.x,y=p.y+1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==4)add(x,y,1);
        if(a[x][y]==2||a[x][y]==3)add(x,y,2);
      }
      if(a[p.x][p.y]==2){
        x=p.x+1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==2)add(x,y,1);
        if(a[x][y]==3||a[x][y]==4)add(x,y,2);
        x=p.x,y=p.y-1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==2||a[x][y]==3)add(x,y,1);
        if(a[x][y]==1||a[x][y]==4)add(x,y,2);
      }
      if(a[p.x][p.y]==3){
        x=p.x-1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==3||a[x][y]==4)add(x,y,1);
        if(a[x][y]==1||a[x][y]==2)add(x,y,2);
        x=p.x,y=p.y-1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==2||a[x][y]==3)add(x,y,1);
        if(a[x][y]==1||a[x][y]==4)add(x,y,2);
      }
      if(a[p.x][p.y]==4){
        x=p.x-1,y=p.y;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==3||a[x][y]==4)add(x,y,1);
        if(a[x][y]==1||a[x][y]==2)add(x,y,2);
        x=p.x,y=p.y+1;
        if(!a[x][y])add(x,y,0);
        if(a[x][y]==1||a[x][y]==4)add(x,y,1);
        if(a[x][y]==2||a[x][y]==3)add(x,y,2);
      }
    }
  }
}
int main(){
  scanf("%d%d",&n,&m);
  for(i=1;i<=n;i++){
    scanf("%s",s+1);
    for(j=1;j<=m;j++)if(s[j]=='0')a[i*2-1][j*2-1]=1,a[i*2][j*2]=3;
    else a[i*2-1][j*2]=2,a[i*2][j*2-1]=4;
  }
  n<<=1,m<<=1;
  for(i=1;i<=n;i++)for(j=1;j<=m;j++){
    if(!a[i][j]&&!v[i][j][0])++pos,bfs(i,j,0);
    if(a[i][j]&&!v[i][j][1])++pos,bfs(i,j,1);
    if(a[i][j]&&!v[i][j][2])++pos,bfs(i,j,2);
  }
  for(i=1;i<=pos;i++)sum[i]=c[i][0]+c[i][2]+(c[i][1]-c[i][2])*pi;
  scanf("%d",&T);
  while(T--){
    scanf("%d%d",&i,&j);
    if(a[i][j]==2||a[i][j]==4){puts("0.0000");continue;}
    if(a[i][j+1]==1||a[i][j+1]==3){puts("0.0000");continue;}
    if(a[i+1][j]==1||a[i+1][j]==3){puts("0.0000");continue;}
    if(a[i+1][j+1]==2||a[i+1][j+1]==4){puts("0.0000");continue;}
    if(!i&&!j){
      if(!a[1][1])ans=sum[v[1][1][0]];
      else if(a[1][1]==1)ans=sum[v[1][1][1]];
      else if(a[1][1]==3)ans=sum[v[1][1][2]];
    }else if(!i){
      if(!a[1][j])ans=sum[v[1][j][0]];
      else if(a[1][j]==2)ans=sum[v[1][j][1]];
      else if(a[1][j]==4)ans=sum[v[1][j][2]];
    }else if(!j){
      if(!a[i][1])ans=sum[v[i][1][0]];
      else if(a[i][1]==4)ans=sum[v[i][1][1]];
      else if(a[i][1]==2)ans=sum[v[i][1][2]];
    }else{
      if(!a[i][j])ans=sum[v[i][j][0]];
      else if(a[i][j]==3)ans=sum[v[i][j][1]];
      else if(a[i][j]==1)ans=sum[v[i][j][2]];
    }
    printf("%.4f\n",ans);
  }
  return 0;
}