23 321 22 13 312 2Sample OutputCase #1:21 6Case #2:18题意:求连通块的个数,以及每个联通块中点的个数。
思路:范围很大,所以要离散化坐标轴。
给出的是障碍点。那么不是障碍的点离散化之后都会是一个矩形。搜索每个点的时候我们每次加上矩形的面积,最后求出总和。
#include <bits/stdc++.h>using namespace std;const int MAXN=300;bool vis[MAXN][MAXN];int x[MAXN],y[MAXN];map<int,int>x_cnt,y_cnt;int pointx[MAXN],pointy[MAXN];long long ans[MAXN];vector<long long>lenx,leny;int n,m,k;long long sum;int dx[4]= {0,0,1,-1};int dy[4]= {1,-1,0,0};void dfs(int x,int y){ vis[x][y]=1; sum+=lenx[x]*leny[y]; for(int i=0; i<4; ++i) { int nx=x+dx[i]; int ny=y+dy[i]; if(nx>=0&&nx<int(lenx.size())&&ny>=0&&ny<int(leny.size())&&!vis[nx][ny]) { dfs(nx,ny); } }}void init(){ x_cnt.clear(); y_cnt.clear(); lenx.clear(); leny.clear(); memset(vis,0,sizeof(vis));}int main(){ int t; int i,j; scanf("%d",&t); for(int tt=1; tt<=t; ++tt) { init(); scanf("%d%d",&n,&m); int cnt1=0,cnt2=0; x[cnt1++]=y[cnt2++]=0; x[cnt1++]=n; y[cnt2++]=m; scanf("%d",&k); for(i=0; i<k; ++i) { scanf("%d%d",&pointx[i],&pointy[i]); x[cnt1++]=pointx[i]; y[cnt2++]=pointy[i]; } sort(x,x+cnt1); sort(y,y+cnt2); cnt1=unique(x,x+cnt1)-x; cnt2=unique(y,y+cnt2)-y; for(i=1; i<cnt1; ++i) { int len=x[i]-x[i-1]; if(len>1) { lenx.push_back(len-1);//不包括障碍点,空白的点连接起来的长度 } lenx.push_back(1);//障碍点单独算,长度必定为1 x_cnt[x[i]]=lenx.size()-1; } for(i=1; i<cnt2; ++i) { int len=y[i]-y[i-1]; if(len>1) { leny.push_back(len-1);//不包括障碍点,空白的点连接起来的长度 } leny.push_back(1);//障碍点单独算,长度必定为1 y_cnt[y[i]]=leny.size()-1; } for(i=0; i<k; ++i) { vis[x_cnt[pointx[i]]][y_cnt[pointy[i]]]=1; } int cnt=0; for(i=0; i<int(lenx.size()); ++i) { for(j=0; j<int(leny.size()); ++j) { if(!vis[i][j]) { sum=0; dfs(i,j); ans[cnt++]=sum; } } } sort(ans,ans+cnt); PRintf("Case #%d:/n",tt); printf("%d/n",cnt); for(i=0; i<cnt; ++i)printf(i==cnt-1?"%I64d/n":"%I64d ",ans[i]); } return 0;}
新闻热点
疑难解答