区域的个数 (坐标离散化)

来源:互联网 发布:网络 克隆 编辑:程序博客网 时间:2024/05/21 01:42

来源  :挑战程序设计

题目:w*h的格子上画了n条垂直或水平的宽度为1的直线。求出这些线将格子划分成了多少个区域。

1<=w,h<=1000000.     1<=n<=500

思路:首先,一般会想到直接进行dfs或bfs,但w,h过大,无法直接搜索。坐标离散化的思想就是把有用的坐标提取出来,再建一个坐标系,把这些坐标按照顺序放在这个坐标系中。本题只需存储直线的x,y坐标和直线前后的。所以大小6n*6n就够了。




坐标离散化前后图


#include<iostream>  #include<cstdio>  #include<cstring>  #include<algorithm>  #include<queue>  #include<vector>  #include<cmath>  #define ll __int64  #define INF 0x3fffffff  #define MAXN 505  using namespace std; int w,h,n;  int dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};  int x1[MAXN],x2[MAXN],Y1[MAXN],y2[MAXN];  bool fld[MAXN*6][MAXN*6];//填充用  struct Point  {      int x,y;      Point(int x_=0,int y_=0):x(x_),y(y_){}  }point[MAXN*MAXN*6*6];    int compress(int *x1,int *x2,int w)  {      vector<int>xs;      for(int i=0;i<n;i++){          for(int d=-1;d<=1;d++){ //与它相邻的以及它本身              int tx1=x1[i]+d,tx2=x2[i]+d;              if(tx1>=1&&tx1<=w) xs.push_back(tx1);              if(tx2>=1&&tx2<=w) xs.push_back(tx2);          }      }      sort(xs.begin(),xs.end());//有重复的,排序      xs.erase(unique(xs.begin(),xs.end()),xs.end());      for(int i=0;i<n;i++){          x1[i]=find(xs.begin(),xs.end(),x1[i])-xs.begin();//离散化后的坐标          x2[i]=find(xs.begin(),xs.end(),x2[i])-xs.begin();      }      return xs.size();  }    void solve()  {      w=compress(x1,x2,w);      h=compress(Y1,y2,h);      //填充有直线的方块      memset(fld,false,sizeof(fld));      for(int i=0;i<n;i++){          for(int y=Y1[i];y<=y2[i];y++){              for(int x=x1[i];x<=x2[i];x++){                  fld[x][y]=true;              }          }      }      //求区域的个数      int ans=0;      for(int x=0;x<w;x++){          for(int y=0;y<h;y++){              if(fld[x][y]){                 continue;              }              ans++;              queue<Point>q;              Point p;              p.x=x;p.y=y;              q.push(p);              while(!q.empty()){                  int sx=q.front().x;                  int sy=q.front().y;                  q.pop();                  for(int i=0;i<4;i++){                      int xx=sx+dir[i][0];                      int yy=sy+dir[i][1];                      if(fld[xx][yy]||xx<0||xx>=w||yy<0||yy>=h) continue;                      q.push(Point(xx,yy));                      fld[xx][yy]=true;                  }              }          }      }      cout<<ans<<endl;  }    int main()  {          cin>>w>>h>>n;      for(int i=0;i<n;i++){          cin>>x1[i];      }      for(int i=0;i<n;i++){          cin>>x2[i];      }      for(int i=0;i<n;i++){          cin>>Y1[i];      }      for(int i=0;i<n;i++){          cin>>y2[i];      }      solve();      return 0;  } 样例输入w=10 h=10 n=5x1={1,1,4,9,10}x2={6,10,4,9,10}y1={4,8,1,1,6}y2={4,8,10,5,10}输出 6


                                             
0 0
原创粉丝点击