因为放一个就需要判断一次,每一次跑一遍全图bfs显然是不现实的
又因为点只有三种,黑白无
所以可以用并查集优化
添加一个棋子就判断周围四个的组别情况
注意出现的情况与答案关系之间的判别
#include<stdio.h> #include<memory.h> int N,M,dx[4]={1,0,-1,0},dy[4]={0,1,0,-1},gp[250010]; char cm[505][505]; int findp(int p){ return p==gp[p]?p:(gp[p]=findp(gp[p])); } int prime(int x,int y){ return x>=0&&y>=0&&x<N&&y<N; } int main(){ int i,j,X,Y,xx,yy,ans=0,g,d1,d2; char C; memset(cm,'.',sizeof cm); for(i=0;i<250000;i++) gp[i]=i; scanf("%d%d",&N,&M); for(i=0;i<M;i++){ scanf("%*c%c%d%d",&C,&X,&Y); ans++; for(g=j=0;j<4;j++){ xx=X-1+dx[j]; yy=Y-1+dy[j]; if(prime(xx,yy)&&cm[xx][yy]==C){ d1=findp(gp[(X-1)*N+(Y-1)]); d2=findp(gp[xx*N+yy]); if(!g){//周围4个位置如果还没有找到一个同集合的,可以直接合并并减少一个答案组 g=1; if(d1!=d2){ if(d1<d2) gp[d2]=d1; else gp[d1]=d2; } ans--; } else{//周围4个位置如果已经找到一个同组的了,只有两个点所在的集合不同时才需要合并并减少一个答案组 if(d1!=d2){ if(d1<d2) gp[d2]=d1; else gp[d1]=d2; ans--; } } } } cm[X-1][Y-1]=C; printf("%d ",ans); } return 0; }