Description
Data Constraint
Solution
我们枚举每2* 2块的情况。设左上角的坐标为(x,y)对于为0的块,我们先给(x,y)(x+2,y+2)的祖先加上
π/4
,然后将(x+1,y+1)与(x+2,y)(x,y+2)合并,给(x+1,y+1)的祖先加上4-
π/2
。对于为1的块则同理,我们先给(x,y+2)(x+2,y)的祖先加上
π/4
,然后将(x+1,y+1)与(x,y)(x+2,y+2)合并,给(x+1,y+1)的祖先加上4-
π/2
。对于祖先的查询用并查集即可。
代码
using namespace std;
const int maxn=205;
const double pai=3.1415926535898;
int a[maxn][maxn],n,m,n1,m1,i,t,j,k,l,x,y,fa[maxn*maxn],p,q;
char s[maxn];
double size[maxn*maxn];
int getfather(int x,double num){
size[x]+=num;
if (fa[x]==x) return x;
fa[x]=getfather(fa[x],num+size[x]);
size[x]=0;
return fa[x];
}
int main(){
// freopen("data.in","r",stdin);freopen("data.out","w",stdout);
scanf("%d%d\n",&n1,&m1);
n=n1*2+1;m=m1*2+1;
for (k=1;k<=n;k++)
for (l=1;l<=m;l++)
fa[(k-1)*m+l]=(k-1)*m+l;
for (i=1;i<=n1;i++){
scanf("%s\n",s+1);
for (j=1;j<=m1;j++){
x=i*2-1;y=j*2-1;
if (s[j]=='0'){
p=getfather((x-1)*m+y,0);
size[p]+=pai/4;
size[x*m+y+1]+=4-pai/2;
p=getfather((x+1)*m+y+2,0);
size[p]+=pai/4;
p=getfather((x-1)*m+y+2,0);
q=fa[x*m+y+1];
if (p!=q) fa[p]=q,size[q]+=size[p],size[p]=0;
p=getfather((x+1)*m+y,0);
if (p!=q) fa[p]=q,size[q]+=size[p],size[p]=0;
}
else{
p=getfather((x-1)*m+y+2,0);
size[p]+=pai/4;
size[x*m+y+1]+=4-pai/2;
p=getfather((x+1)*m+y,0);
size[p]+=pai/4;
p=getfather((x-1)*m+y,0);
q=fa[x*m+y+1];
if (p!=q) fa[p]=q,size[q]+=size[p],size[p]=0;
p=getfather((x+1)*m+y+2,0);
if (p!=q) fa[p]=q,size[q]+=size[p],size[p]=0;
}
}
}
scanf("%d",&n);
for (i=1;i<=n;i++){
scanf("%d%d",&x,&y);x++;y++;
q=getfather((x-1)*m+y,0);
printf("%.4lf\n",size[q]);
}
}