题目链接:https://vj.e949.cn/b743540e901f680c3f865e202a43ca28?v=1543480981
题意:
给你二维坐标系上的n(n<=50)个矩形,问这些矩形把二维平面分成了几部分。
做法:
队友的做法好神奇。队友把点离散化,然后每个点的坐标乘2,把划线的地方打上标记,这样可以使没有被覆盖到的空位留出至少一个点的空位,然后用搜索把点覆盖。
我敲的做法是用二进制优化,因为最多有50个矩形,所以被一个矩形覆盖的地方我用一位二进制表示,然后通过搜索去找与这个数字相似的(即被同样覆盖的地方),再打标记。
代码1:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1e9;
map<ll,ll> mpx,mpy;
map<ll,ll>::iterator it;
ll mp[255][255];
ll xl[55],xr[55],yl[55],yh[55],vis[255][255],numx,numy;
void dfs(int x,int y,ll a){
if(x<0||x>numx||y<0||y>numy||vis[x][y]||mp[x][y]!=a) return ;
vis[x][y]=1;
dfs(x+1,y,a);
dfs(x-1,y,a);
dfs(x,y+1,a);
dfs(x,y-1,a);
}
int main(){
int n;
while(~scanf("%d",&n)){
if(n==0) break;
memset(vis,0,sizeof(vis));
memset(mp,0,sizeof(mp));
mpx.clear(); mpy.clear();
mpx[-inf]=1,mpx[inf]=1,mpy[-inf]=1,mpy[inf]=1;
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld%lld",&xl[i],&yh[i],&xr[i],&yl[i]);
mpx[xl[i]]=1,mpx[xr[i]]=1,mpy[yl[i]]=1,mpy[yh[i]]=1;
}
numx=0,numy=0;
for(it=mpx.begin();it!=mpx.end();it++)
it->second=++numx;
for(it=mpy.begin();it!=mpy.end();it++){
it->second=++numy;
//cout<<it->first<<" "<<it->second<<endl;
}
for(int i=1;i<=n;i++){
for(int j=mpx[xl[i]];j<=mpx[xr[i]]-1;j++){
for(int k=mpy[yl[i]];k<=mpy[yh[i]]-1;k++){
mp[j][k]|=(1ll<<(i-1));
}
}
}
int ans=0;
for(int i=1;i<=numx;i++){
for(int j=1;j<=numy;j++){
if(!vis[i][j]){
ans++;
dfs(i,j,mp[i][j]);
}
}
}
printf("%d\n",ans);
}
return 0;
}
代码2。
#include<bits/stdc++.h>
using namespace std;
#define pa pair<int,int>
int Map[405][405],vis[405][405];
struct node
{
int x1,y1,x2,y2;
}p[155];
int x[405],y[405];
int n;
queue<pa>Q;
int xmov[]={1,0,-1,0};
int ymov[]={0,1,0,-1};
void bfs(int sx,int sy)
{
Q.push({sx,sy});
vis[sx][sy]=1;
while(!Q.empty())
{
int x=Q.front().first,y=Q.front().second,nx,ny;
Q.pop();
for(int i=0;i<4;i++)
{
nx=x+2*xmov[i],ny=y+2*ymov[i];
if(nx>201||nx<1||ny>201||ny<1||Map[nx-xmov[i]][ny-ymov[i]]==1||vis[nx][ny]==1)
continue;
vis[nx][ny]=1;
Q.push({nx,ny});
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
int x1,x2,y1,y2;
memset(vis,0,sizeof(vis));
memset(Map,0,sizeof(Map));
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
x[i*2-1]=p[i].x1,x[i*2]=p[i].x2;
y[i*2-1]=p[i].y1,y[i*2]=p[i].y2;
}
sort(x+1,x+1+2*n),sort(y+1,y+1+2*n);
int allx=unique(x+1,x+1+2*n)-x-1;
int ally=unique(y+1,y+1+2*n)-y-1;
for(int i=1;i<=n;i++)
{
p[i].x1=(lower_bound(x+1,x+1+allx,p[i].x1)-x)*2;
p[i].x2=(lower_bound(x+1,x+1+allx,p[i].x2)-x)*2;
p[i].y1=(lower_bound(y+1,y+1+ally,p[i].y1)-y)*2;
p[i].y2=(lower_bound(y+1,y+1+ally,p[i].y2)-y)*2;
//cout<<p[i].x1<<" "<<p[i].y2<<endl;
for(int j=p[i].x1;j<=p[i].x2;j++)
Map[j][p[i].y1]=Map[j][p[i].y2]=1;
for(int j=p[i].y2;j<=p[i].y1;j++)
Map[p[i].x1][j]=Map[p[i].x2][j]=1;
}
int ans=0;
for(int i=1;i<=201;i+=2)
{
for(int j=1;j<=201;j+=2)
{
if(!vis[i][j])
{
bfs(i,j);
ans++;
}
}
}
printf("%d\n",ans);
}
return 0;
}