题库6665传递门
题意,在坐标轴上给出两个矩形的坐标,判断两个矩形能将无限的空间分成几部分
两种做法:
一、直接用给的坐标判断两个矩形的关系(相交还是分离还是重叠),直接写的话要写很多个if,很麻烦所以建议食用第二种解法;第一种解法可以点传送门
二、将坐标离散化,用dfs求连通块:
离散化这里借鉴焦队的博客传送门
此处分别对x和y坐标进行离散化处理
for(int i = 1;i <= 4;i++){
scanf("%d%d",&x[i],&y[i]);
a[i] = x[i];
b[i] = y[i];
}
sort(a+1,a+5);
sort(b+1,b+5);
int la = unique(a+1,a+5) - a - 1;
int lb = unique(b+1,b+5) - b - 1;
for(int i = 1;i <= 4;i++){
x[i] = lower_bound(a+1,a+5,x[i]) - a;
y[i] = lower_bound(b+1,b+5,y[i]) - b;
}
为了以防离散化坐标后,原本不重叠的坐标变重叠,这里将坐标乘二,防止出现错误(具体什么原因我也不知道,我是看别人博客的嘿嘿)
for(int i = 1;i <= 4;i++){
x[i] *= 2;
y[i] *= 2;
}
离散化完坐标后,将矩形构图,然后直接用dfs判断有多少连通块就可以了
直接给出AC代码
#include<bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
int x[5],y[5];
int a[5],b[5];//离散化辅助数组
int aa[10][10],vis[10][10];
int xx[4] = {1,0,-1,0};
int yy[4] = {0,1,0,-1};
void dfs(int c,int d,int flag){
for(int i = 0;i < 4;i++){
int x_x = c + xx[i];
int y_y = d + yy[i];
if(x_x >= 0 && x_x <= 9 && y_y >= 0 && y_y <= 9 && aa[x_x][y_y] == 0 && vis[x_x][y_y] == 0){
vis[x_x][y_y] = flag;
dfs(x_x,y_y,flag);
}
}
}
int main(){
int t;
while(~scanf("%d",&t)){
while(t--){
for(int i = 1;i <= 4;i++){
scanf("%d%d",&x[i],&y[i]);
a[i] = x[i];
b[i] = y[i];
}
sort(a+1,a+5);
sort(b+1,b+5);
int la = unique(a+1,a+5) - a - 1;
int lb = unique(b+1,b+5) - b - 1;
for(int i = 1;i <= 4;i++){
x[i] = lower_bound(a+1,a+5,x[i]) - a;
y[i] = lower_bound(b+1,b+5,y[i]) - b;
}
for(int i = 1;i <= 4;i++){
x[i] *= 2;
y[i] *= 2;
}//乘2防止离散化后重叠
//构图
mem(vis,0);
mem(aa,0);
for(int i=x[1]; i<=x[2]; i++)
{
aa[i][y[1]]=1,aa[i][y[2]]=1;
}
for(int i=y[1]; i<=y[2]; i++)
{
aa[x[1]][i]=1,aa[x[2]][i]=1;
}
for(int i=x[3]; i<=x[4]; i++)
{
aa[i][y[3]]=1,aa[i][y[4]]=1;
}
for(int i=y[3]; i<=y[4]; i++)
{
aa[x[3]][i]=1,aa[x[4]][i]=1;
}
int ans=0;
int flag=1;
for(int i=0; i<=9; i++)
{
for(int j=0; j<=9; j++)
{
if(aa[i][j]==0&&vis[i][j]==0)
{
vis[i][j]=flag;
dfs(i,j,flag);
flag++;
}
}
}
printf("%d\n",flag-1);
}
}
}