2019多校Calabash and Landlord_hdu6665(区域染色分块)

题目:Calabash and Landlord

问:在平面中的两个矩形可以将平面分成多少个区域?

分析:可以看成是对区域进行染色。

先把点离散化,并且在离散化时,将值设为原本离散化值的2倍--->为了使矩形留出空格成块

否则,如(0,0)和(1,1)组成的矩形在整个图(假设边为5的正方形图)中显示会如下所示
-1 -1 0 0 0 
-1 -1 0 0 0 
 0  0 0 0 0 
 0  0 0 0 0 
 0  0 0 0 0 (-1表示矩形的边,0表示空白处)

而因为矩形内也存在区域 所以正确的图应该如下
-1 -1 -1 0 0 
-1  0 -1 0 0 
-1 -1 -1 0 0 
 0  0  0 0 0 
 0  0  0 0 0

所以离散化时应该将值设为原本的2倍~

然后跑一遍整幅图(此处大小设为了10*10),每跑完一次dfs相当于跑完一个区域,所以跑了多少遍dfs就是有多少个区域-->即答案。 

#include <bits/stdc++.h>
using namespace std;
#define  ll long long
#define N 10
int a[N][N];
int x[5],y[5];
void init() {
	int m[5],n[5];
	for(int i=0; i<4; i++) {
		m[i]=x[i];
		n[i]=y[i];
	}
	sort(m,m+4);
	sort(n,n+4);
	int len1=unique(m,m+4)-m;
	int len2=unique(n,n+4)-m;
	for(int i=0; i<4; i++) {
		x[i]=2*(lower_bound(m,m+4,x[i])-m+1);//为了正方形内空格  可打表观察 
		y[i]=2*(lower_bound(n,n+4,y[i])-n+1);
	}
}
int zb[4][2]= {0,1,1,0,-1,0,0,-1};
int ans=0;
void dfs(int x,int y) {
	int nx,ny;
	for(int i=0; i<4; i++) {
		nx=x+zb[i][0];
		ny=y+zb[i][1];
		if(nx>=0&&nx<N&&y>=0&&y<N&&a[nx][ny]==0) {
			a[nx][ny]=ans;
			dfs(nx,ny);
		}
	}
}
int main() {
	int t;
	scanf("%d",&t);
	while(t--) {
		for(int i=0; i<4; i++) {
			scanf("%d%d",&x[i],&y[i]);
		}
		init();//离散化
		memset(a,0,sizeof(a));
		for(int j=0; j<2; j++) {
			for(int i=x[2*j]; i<=x[2*j+1]; i++) {
				a[i][y[2*j]]=a[i][y[2*j+1]]=-1;
			}
			for(int i=y[2*j]; i<=y[2*j+1]; i++) {
				a[x[2*j]][i]=a[x[2*j+1]][i]=-1;
			}
		}

		ans=0;
		for(int i=0; i<N; i++) {
			for(int j=0; j<N; j++) {
				if(a[i][j]==0) {
					ans++;
					dfs(i,j);
				}
			}
		}

		printf("%d\n",ans);

	}

	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值