【问题描述】
w*h的格子画了n条或垂直或水平宽度为1的直线,求出这些格子被划分成了多少个4连块(上、下、左、右连通)。
【输入格式】
第一行包含两个整数:w和h,表示矩阵的列数和行数(行列编号都从1开始)。
第二行包含一个整数n,表示有n条直线。
接下来的n行,每行包含四个整数:x1,y1,x2,y2,表示一条直线的列号和行号。
【输出格式】
一个整数,表示区域数量。
【输入样例】
10 10
5
1 4 6 4
1 8 10 8
4 1 4 10
9 1 9 5
10 6 10 10
【输出样例】
6
【数据范围】
1<=w,h<=1000000 , 1<=n<=500
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#define maxn 5005
using namespace std;
struct data
{
int p,q;
}e[maxn*maxn];
int x1[maxn],x2[maxn],y1[maxn],y2[maxn],x[maxn],y[maxn];
int n,m,k,u=1,v=1,front,rear,ans=0;
bool vis[maxn][maxn];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int read()
{
int x=0,ok=0;
char ch;
ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
while((ch>='0'&&ch<='9')||ch=='-')
{
if(ch=='-') ok=1;
else x=x*10+ch-'0';
ch=getchar();
}
return ok==1?-x:x;
}
void in()
{
n=read();
m=read();
k=read();
for(int i=1;i<=k;i++)
{
x1[i]=read();
y1[i]=read();
x2[i]=read();
y2[i]=read();
}
int cnt1=0,cnt2=0;
for(int i=1;i<=k;i++) //将端点及其上下或左右的点存到x和y中
{
x[++cnt1]=x1[i];
if(x1[i]-1>0) x[++cnt1]=x1[i]-1;
if(x1[i]+1<n) x[++cnt1]=x1[i]+1;
x[++cnt1]=x2[i];
if(x2[i]-1>0) x[++cnt1]=x2[i]-1;
if(x2[i]+1<n) x[++cnt1]=x2[i]+1;
y[++cnt2]=y1[i];
if(y1[i]-1>0) y[++cnt2]=y1[i]-1;
if(y1[i]+1<m) y[++cnt2]=y1[i]+1;
y[++cnt2]=y2[i];
if(y2[i]-1>0) y[++cnt2]=y2[i]-1;
if(y2[i]+1<m) y[++cnt2]=y2[i]+1;
}
sort(x+1,x+cnt1+1);
sort(y+1,y+cnt2+1); //本来是乱序,现在把需要的x和y有小到大排序
for(int i=2;i<=cnt1;i++) if(x[i]!=x[i-1]) x[++u]=x[i];
for(int i=2;i<=cnt2;i++) if(y[i]!=y[i-1]) y[++v]=y[i]; //去重
for(int i=1;i<=k;i++)
{
x1[i]=lower_bound(x+1,x+u+1,x1[i])-x;
x2[i]=lower_bound(x+1,x+u+1,x2[i])-x;
y1[i]=lower_bound(y+1,y+v+1,y1[i])-y;
y2[i]=lower_bound(y+1,y+v+1,y2[i])-y; //找离散化后线(障碍物)的坐标
}
for(int i=1;i<=k;i++) //生成地图
{
for(int j=x1[i];j<=x2[i];j++)
for(int t=y1[i];t<=y2[i];t++)
vis[j][t]=1;
}
}
void bfs(int x,int y)
{
front=rear=1;
e[rear++]=(data){x,y};
vis[x][y]=1;
while(front!=rear)
{
data i=e[front++];
for(int k=0;k<4;k++)
{
int di=i.p+dx[k],dj=i.q+dy[k];
if(vis[di][dj]) continue;
if(di<1||dj<1||di>u||dj>v) continue;
e[rear++]=(data){di,dj};
vis[di][dj]=1;
}
}
}
void task()
{
/*
for(int i=1;i<=u;i++)
{
for(int j=1;j<=v;j++) printf("%d ",vis[i][j]);
printf("\n");
}
*/
for(int i=1;i<=u;i++)
for(int j=1;j<=v;j++) if(!vis[i][j])
{
ans++;
bfs(i,j);
}
printf("%d",ans);
}
int main()
{
//freopen("in1.txt","r",stdin);
//freopen("out.txt","w",stdout);
in();
task();
return 0;
}