2 条题解

  • 0
    @ 2024-6-10 20:41:02

    本题实际上是求一个点所在连通块内有多少个点,可以用并查集来解决。首先dfs找出一个点所在连通块内所有的点并计算个数,然后把它们合并,并记录下答案。最后对于每一组询问在线回答即可。

    时间复杂度为 O(n2)O(n^2) 左右。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1005,d[4][2]={1,0,-1,0,0,1,0,-1}; 
    int n,m,dsu[N*N],ans[N*N];
    bool c[N][N],vis[N][N];
    // 并查集模板
    int find(int x){
    	return dsu[x]==x?x:dsu[x]=find(dsu[x]);
    }
    inline void merge(int a,int b){
    	dsu[find(a)]=find(b);
    }
    struct node{
    	int x,y;
    };
    vector<node> vec; // 用于存储当前连通块内的点
    int dfs(int x,int y){ // 深搜找出连通块内的点
    	vis[x][y]=1;
    	vec.push_back({x,y});
    	int cnt=1;
    	for(int i=0;i<4;i++){
    		int xx=x+d[i][0],yy=y+d[i][1];
    		if(xx>=1&&yy>=1&&xx<=n&&yy<=n&&!vis[xx][yy]&&c[x][y]^c[xx][yy])
    			cnt+=dfs(xx,yy);
    	}
    	return cnt;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++){
    			char p;
    			cin>>p;
    			c[i][j]=p=='1';
    			dsu[(i-1)*n+j]=(i-1)*n+j; // 并查集初始化
    		}
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			if(!vis[i][j]){
    				int cnt=dfs(i,j);
    				for(auto i=vec.begin();i!=vec.end()-1;i++){
    					node k1=*i,k2=*(i+1);
    					merge((k1.x-1)*n+k1.y,(k2.x-1)*n+k2.y); // 将连通块内所有的点合并
    				}
    				ans[find((vec[0].x-1)*n+vec[0].y)]=cnt; // 记录答案
    				vec.clear(); // 清空
    			}
    	for(int i=1,x,y;i<=m;i++){
    		scanf("%d%d",&x,&y);
    		printf("%d\n",ans[find((x-1)*n+y)]); // 在线回答
    	}
    	return 0;
    }
    
    • 0
      @ 2024-6-8 20:24:58
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1001;
      int n,m,x,y,cnt,d[1001][1001];
      int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
      char c[N][N];
      vector<pair<int,int>>e;
      void dfs(int x,int y)
      {
          d[x][y]=1;
          cnt+=1;
          e.push_back({x,y});
          for(int i=0;i<=3;i+=1)
          {
              int _x=x+dx[i];
              int _y=y+dy[i];
              if(_x>=1&&_x<=n&&_y>=1&&_y<=n&&c[x][y]!=c[_x][_y]&&d[_x][_y]==0)dfs(_x,_y);
          }
      }
      int main()
      {
          cin>>n>>m;
          for(int i=1;i<=n;i+=1)cin>>c[i]+1;
          while(m--)
          {
              cin>>x>>y;
              if(!d[x][y])
              {
                  e.clear();
                  cnt=0;
                  dfs(x,y);
                  for(auto i:e)d[i.first][i.second]=cnt;
              }
              cout<<d[x][y]<<'\n';
          }
      }
      
      • 1

      信息

      ID
      772
      时间
      1000ms
      内存
      128MiB
      难度
      5
      标签
      递交数
      104
      已通过
      42
      上传者