给出一个1e9*1e9的矩阵,矩阵中有两百个坏点。问这些坏点将矩阵分成了几个联通块,每个块的大小是多少
这类问题需要将大矩阵离散成小矩阵。离散之后的小矩阵中,每一个小矩形都和同行小矩形同高
离散化处理步骤:先对点排序,去重。在不相邻的点中插入一个点。然后建立原来的点和压缩后的点间的映射关系
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=408; struct poi{ int x,y; }f[maxn]; int lena[maxn],lenb[maxn]; int a[maxn],b[maxn]; int idx,idy; int mp[maxn][maxn]; bool vis[maxn][maxn]; map<int,int> X,Y; int dir[4][2]={0,1,1,0,0,-1,-1,0}; ll dfs(int x,int y) { int nx,ny; ll xx=1; ll sum=xx*lena[x]*lenb[y]; vis[x][y]=true; for(int i=0;i<4;i++) { nx=x+dir[i][0]; ny=y+dir[i][1]; if(mp[nx][ny]!=-1&&!vis[nx][ny]) sum+=dfs(nx,ny); } return sum; } ll ans[maxn]; void solve(int n,int m) { int idx=0; memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(!vis[i][j]&&mp[i][j]!=-1) { ans[idx++]=dfs(i,j); } printf("%d ",idx); sort(ans,ans+idx); for(int i=0;i<idx;i++) { if(i!=0) printf(" "); printf("%lld",ans[i]); } printf(" "); } int main() { int n,m,q; int t; scanf("%d",&t); int cas=1; while(t--) { scanf("%d%d%d",&n,&m,&q); idx=0;idy=0; a[idx++]=0;b[idy++]=0; a[idx++]=n;b[idy++]=m; for(int i=0;i<q;i++) { scanf("%d%d",&f[i].x,&f[i].y); a[idx++]=f[i].x;b[idy++]=f[i].y; } sort(a,a+idx);sort(b,b+idy); int sn=unique(a,a+idx)-a; int sm=unique(b,b+idy)-b; X.clear();Y.clear(); int dn=0,dm=0; for(int i=1;i<sn;i++) { if(a[i]>a[i-1]+1) { lena[++dn]=a[i]-a[i-1]-1; } lena[++dn]=1; X[a[i]]=dn; } for(int i=1;i<sm;i++) { if(b[i]>b[i-1]+1) lenb[++dm]=b[i]-b[i-1]-1; lenb[++dm]=1; Y[b[i]]=dm; } memset(mp,-1,sizeof(mp)); for(int i=1;i<=dn;i++) for(int j=1;j<=dm;j++) mp[i][j]=0; for(int i=0;i<q;i++) { int x=f[i].x,y=f[i].y; mp[X[x]][Y[y]]=-1; } /*for(int i=1;i<=dn;i++) { for(int j=1;j<=dm;j++) printf("%d ",mp[i][j]); printf(" "); }*/ printf("Case #%d: ",cas++); solve(dn,dm); } return 0; }