/**//* 题意:给出n*n的蛋糕 现要切蛋糕,同时询问点(x1,y1) (x2,y2)是否还连通 反过来做 用并查集即可 对于切割,要处理好! color[i,j]=1表示格子[i,j]的右边缘被切 color[i,j]=2表示格子[i,j]的下边缘被切 一开始读入所有,全部先切割完(即染色) 然后两个for 对每个格子,向其右边缘、下边缘,看能不能合并 反过来做即可
http://acm.ustc.edu.cn/ustcoj/problem.php?id=1206 */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1000,maxq=100000; struct op { int op; int x1,y1,x2,y2; } p[maxq]; int n,q; bool init() { scanf("%d%d",&n,&q); if(n==0&&q==0) return false; for(int i=0;i<q;i++) { char s[1024]; scanf("%s%d%d%d%d",s,&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2); if(*s=='c') p[i].op=0; else p[i].op=1; if(p[i].y1==p[i].y2&&p[i].x1>p[i].x2) swap(p[i].x1,p[i].x2); else if(p[i].x1==p[i].x2&&p[i].y1>p[i].y2) swap(p[i].y1,p[i].y2); } return true; } int f[maxn*maxn],r[maxn*maxn]; int find(int u) { if(f[u]==u) return u; return f[u]=find(f[u]); } void combine(int u,int v) { u=find(u); v=find(v); if(r[u]<r[v]) f[u]=v; else if(r[u]>r[v]) f[v]=f[u]; else { f[u]=v; r[v]++; } } inline int adr(int i,int j,int n) { return i*n+j; } void solve() { static char b[maxn][maxn],ans[maxq]; memset(b,0,sizeof(b)); for(int i=0;i<q;i++) if(p[i].op==0) { if(p[i].y1==p[i].y2) { int y=p[i].y1-1; for(int j=p[i].x1;j<p[i].x2;j++) b[y][j]|=1; } else { int x=p[i].x1-1; for(int j=p[i].y1;j<p[i].y2;j++) b[j][x]|=2; } } memset(r,0,sizeof(r)); for(int i=0;i<n*n;i++) f[i]=i;
//枚举所有格子 向其右边缘、下边缘 看能不能合并 for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(i<n-1&&(b[i][j]&1)==0) combine(adr(i,j,n),adr(i+1,j,n)); if(j<n-1&&(b[i][j]&2)==0) combine(adr(i,j,n),adr(i,j+1,n)); } memset(ans,255,sizeof(ans)); for(int i=q-1;i>=0;i--) { if(p[i].op==0) { if(p[i].y1==p[i].y2) { int y=p[i].y1-1; for(int j=p[i].x1;j<p[i].x2;j++) combine(adr(y,j,n),adr(y+1,j,n)); } else { int x=p[i].x1-1; for(int j=p[i].y1;j<p[i].y2;j++) combine(adr(j,x,n),adr(j,x+1,n)); } } else { if(find(adr(p[i].y1-1,p[i].x1-1,n))==find(adr(p[i].y2-1,p[i].x2-1,n))) ans[i]=1; else ans[i]=0; } } for(int i=0;i<q;i++) if(ans[i]==0) puts("No"); else if(ans[i]==1) puts("Yes"); } int main() { //freopen("tb.in","r",stdin); //freopen("tb.out","w",stdout); while(init()) solve(); //fclose(stdin); //fclose(stdout); return 0; }
|