Topic:
Ideas:
1, the input data offline, first all the black lines are drawn, statistics on the remaining number of white connected blocks, DFS process to put a connected block into a set.
2, backward to eliminate the black line, if the current block A is white, see if he is surrounded by white block: There is white block B, see the ancestors of A and B is not the same, the same word pass, otherwise merge connected blocks and the number of white connected blocks minus one (of course the first one is skipped). Four weeks is full of black blocks, the number of white connected blocks plus one.
3, use the stack to store each step of the answer, the final output can be.
PS: Read the wrong data range, card three days, said the first two days the answer state is WA in Test5, the third day became Memor limit exceeded, and then found his mistake. Food is the original sin Ah!!
Code:
#include <bits/stdc++.h>#defineINF 1e9#defineFRE () freopen ("In.txt", "R", stdin)using namespaceStd;typedefLong Longll;Constll MOD =2147493647;Const intMAXN = 1e3+Ten;intmp[maxn][maxn],fa[maxn*MAXN],VIS[MAXN][MAXN];intdir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};structlabel{intr1,c1; intR2,C2;} L[MAXN*Ten];intR,c,q,num_white;intGetId (intXinty) { returnx*c+y;}voidinit () {Num_white=0; Memset (MP,0,sizeof(MP)); memset (Vis,0,sizeof(VIS)); for(inti =0; i<maxn*maxn; i++) {Fa[i]=i; } return;}intFind (intx) { returnFa[x]==x? X:FA[X] =Find (fa[x]);}voidinput () {intX1,x2,y1,y2; for(inti =0; i<q; i++) {scanf ("%d%d%d%d",&l[i].c1,&l[i].r1,&l[i].c2,&L[I].R2); L[i].c1--, l[i].c2--, l[i].r1--, l[i].r2--; if(l[i].r1==l[i].r2) { intx =L[i].r1; for(intj = l[i].c1; j<=l[i].c2; J + +) Mp[x][j]++; } Else if(l[i].c1==l[i].c2) { inty =l[i].c2; for(intj = l[i].r1; j<=l[i].r2; J + +) Mp[j][y]++; } }}BOOLInsideintXinty) { if(x>=0&& X<r && y>=0&& y<c)return true; return false;}voidDfsintXintYintIID) { intID =getId (x, y); Vis[x][y]=1; Fa[id]=IID; for(inti =0; i<4; i++) { inttx = x+dir[i][0],ty = y+dir[i][1]; if(Inside (tx,ty) &&!mp[tx][ty] &&!Vis[tx][ty]) {DFS (TX,TY,IID); } } return;}BOOL_union (intXinty) { inttx = Find (x), Ty =Find (y); if(tx!=ty) {FA[TX]=Ty; return true; } return false;}voidSolveintXinty) { intf =0, Isfirst =0; for(inti =0; i<4; i++) { inttx = x+dir[i][0],ty = y+dir[i][1]; if(Inside (tx,ty)) {if(!Mp[tx][ty]) {f=1; if(_union (getId (x, y), GetId (Tx,ty))) {Isfirst++; if(Isfirst = =1) Continue; ElseNum_white--; } } } } if(!f) Num_white++;}voidCheck () { for(inti =0; i<r; i++) { for(intj =0; j<c; J + +) {printf ("%d", Mp[i][j]); } printf ("\ n"); } cout<<"GG"<<Endl;}voidCountwhite () { for(inti =0; i<r; i++) { for(intj =0; j<c; J + +) { intID =getId (I,J); if(!mp[i][j] &&!Vis[i][j]) {DFS (I,J,ID); Num_white++; } } }}intMain () {//FRE ();scanf"%d%d%d",&c,&r,&q); Init (); Input (); Countwhite (); Stack<int>ans; for(inti = q1; i>=0; i--) {Ans.push (num_white); intX1 = l[i].r1,x2=l[i].r2,y1=l[i].c1,y2=l[i].c2; if(x1==x2) { for(intJ=y1; j<=y2; J + +) {Mp[x1][j]--; if(mp[x1][j]==0) {solve (X1,J); } } } Else if(y1==y2) { for(intj=x1; j<=x2; J + +) {Mp[j][y1]--; if(mp[j][y1]==0) {solve (j,y1); } } } //check (); } while(!Ans.empty ()) {printf ("%d\n", Ans.top ()); Ans.pop (); } return 0;}/*4 6 2 2 (3 4, 5 3, 6 4, 6 4 6*//*13343*/
View Code
GYM-101550A (artwork reverse + and check set)