您的位置:首页 > 其它

ACM 二维离散化模板 hdu5925

2017-10-18 16:45 253 查看
hdu5925

给出一个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\n",idx);
sort(ans,ans+idx);
for(int i=0;i<idx;i++)
{
if(i!=0)	printf(" ");
printf("%lld",ans[i]);
}
printf("\n");
}
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("\n");
}*/
printf("Case #%d:\n",cas++);
solve(dn,dm);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: