BZOJ3046 : lagoon
码农题,拆点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; }