[UVALive] - 5817 Dhaka 2011 I - Truchet Tiling
阿新 • • 發佈:2018-11-05
每塊磚可以拆成三個小塊,建圖處理每個塊的總面積和每個小塊的歸屬
查詢一個點的時候尋找一個最近的小塊進行查詢
#include<bits/stdc++.h> using namespace std; #define N 115 #define M 40000 const double pi=acos(-1); char s[N][N]; int n,m,S[M],tot; bool vis[M]; struct edge{int v,n;}e[M*10]; inline void Push(int u,int v) { e[++tot]=(edge){v,S[u]};S[u]=tot; } inline int id(int x,int y,int c) { return ((x-1)*m+y)*3-c+1; } struct node{int t,a,b;}f[M]; int gf(int a) { return f[a].t==a?a:f[a].t=gf(f[a].t); } inline void merge(node &a,node &b) { a.a+=b.a; a.b+=b.b; b.t=a.t; } inline void bfs(int st) { queue<int> Q; Q.push(st); vis[st]=1; while (!Q.empty()) { int h=Q.front(); Q.pop(); for (int i=S[h];i;i=e[i].n) { if (!vis[e[i].v]) { vis[e[i].v]=1; Q.push(e[i].v); } if (gf(h)!=gf(e[i].v)) merge(f[gf(h)],f[gf(e[i].v)]); } } } inline void prepare() { int lim=id(n,m,1); memset(vis+1,0,lim*sizeof(bool)); tot=0; memset(S+1,0,lim<<2); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { if (i<n) { if (s[i][j]=='0') { if (s[i+1][j]=='0') { Push(id(i,j,2),id(i+1,j,1)); Push(id(i,j,3),id(i+1,j,2)); } else { Push(id(i,j,2),id(i+1,j,2)); Push(id(i,j,3),id(i+1,j,3)); } } else { if (s[i+1][j]=='0') { Push(id(i,j,1),id(i+1,j,1)); Push(id(i,j,2),id(i+1,j,2)); } else { Push(id(i,j,1),id(i+1,j,2)); Push(id(i,j,2),id(i+1,j,3)); } } } if (j<m) { if (s[i][j]=='0') { if (s[i][j+1]=='0') { Push(id(i,j,2),id(i,j+1,1)); Push(id(i,j,3),id(i,j+1,2)); } else { Push(id(i,j,2),id(i,j+1,2)); Push(id(i,j,3),id(i,j+1,1)); } } else { if (s[i][j+1]=='0') { Push(id(i,j,3),id(i,j+1,1)); Push(id(i,j,2),id(i,j+1,2)); } else { Push(id(i,j,2),id(i,j+1,1)); Push(id(i,j,3),id(i,j+1,2)); } } } } for (int i=1;i<=lim;i++) { int flag=(i%3==2)?1:0; f[i]=(node){i,flag,flag^1}; } for (int i=1;i<=lim;i++) if (!vis[i]) bfs(i); } inline double get(int p) { int tp=gf(p); return f[tp].a*(4-pi/2)+f[tp].b*(pi/4); } inline double find(int x,int y) { int X=x/2+1,Y=y/2+1; if (((x&1)==0 && (y&1)!=0)||((y&1)==0 && (x&1)!=0)) return 0; if (X==n+1 && Y==m+1) { if (s[n][m]=='0') return get(id(n,m,3)); return get(id(n,m,2)); } if (X==n+1) { if (s[n][Y]=='0') return get(id(n,Y,2)); return get(id(n,Y,1)); } if (Y==m+1) { if (s[X][m]=='0') return get(id(X,m,2)); return get(id(X,m,3)); } if ((x&1) && (y&1)) return get(id(X,Y,2)); if (s[X][Y]=='0') return get(id(X,Y,1)); return get(id(X,Y,2)); } inline void solve() { scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%s",s[i]+1); prepare(); int Q; scanf("%d",&Q); for (int x,y;Q--;) { scanf("%d%d",&x,&y); printf("%.4lf\n",find(x,y)); } } int main() { int T; scanf("%d",&T); for (int t=1;t<=T;t++) printf("Case %d:\n",t),solve(); }