离散化 区域个数《挑战程序设计竞赛》164页

来源:互联网 发布:13米半挂车运费计算法 编辑:程序博客网 时间:2024/05/20 08:26
【问题描述】  

  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 5005using 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;}
0 0
原创粉丝点击