区域的个数

  • 问题描述: w*h的格子上画了n条或垂直或水平的宽度为1的直线,求这些直线将格子划分成了多少个区域。
  • 限制条件:
    1≤w,h≤1000000
    1≤n≤500
  • 题解:这题的关键在于我们没法创建w*h的数组,因为太大了,所以要进行坐标离散化,数组里只需要存储有直线的行列以及其前后的行列就足够了,这样的话6n*6n的空间就可以了。
  • 代码:
      1 #include <cstdio>
      2 #include <cctype>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <vector>
      7 #include <queue>
      8 #include <utility>
      9 #define number s-'0'
     10 
     11 using namespace std;
     12 
     13 const int MAX_N=600;
     14 const long long INF=0x3f3f3f3f;
     15 const int dx[4]{-1,0,0,1};
     16 const int dy[4]{0,1,-1,0};
     17 int N,H,W;
     18 int X1[MAX_N],X2[MAX_N],Y1[MAX_N],Y2[MAX_N];
     19 bool fld[MAX_N*6][MAX_N*6];
     20 
     21 void read(int &x){
     22     char s;
     23     x=0;
     24     bool flag=0;
     25     while(!isdigit(s=getchar()))
     26         (s=='-')&&(flag=true);
     27     for(x=number;isdigit(s=getchar());x=x*10+number);
     28     (flag)&&(x=-x);
     29 }
     30 
     31 void write(int x)
     32 {
     33     if(x<0)
     34     {
     35         putchar('-');
     36         x=-x;
     37     }
     38     if(x>9)
     39         write(x/10);
     40     putchar(x%10+'0');
     41 }
     42 
     43 int compress(int *x1, int *x2, int w);
     44 
     45 int main()
     46 {
     47     read(W);read(H);read(N);
     48     for (int i=0; i<N; i++)
     49     {
     50         read(X1[i]);read(Y1[i]);
     51         read(X2[i]);read(Y2[i]);
     52     }
     53     W=compress(X1, X2, W);
     54     H=compress(Y1, Y2, H);
     55     memset(fld, 0, sizeof(fld));
     56     for (int i=0; i<N; i++)
     57         for (int y=Y1[i]; y<=Y2[i]; y++)
     58             for (int x=X1[i]; x<=X2[i]; x++)
     59                 fld[y][x]=true;
     60     int ans=0;
     61     for (int y=0; y<H; y++)
     62     {
     63         for (int x=0; x<W; x++)
     64         {
     65             if (fld[x][y]) continue;
     66             ans++;
     67             queue<pair<int, int>> que;
     68             que.push(make_pair(x,y));
     69             while (!que.empty())
     70             {
     71                 int sx=que.front().first, sy=que.front().second;
     72                 que.pop();
     73                 for (int i=0; i<4; i++)
     74                 {
     75                     int tx=sx+dx[i], ty=sy+dy[i];
     76                     if (tx<0 || tx>=W || ty<0 || ty>=H) continue;
     77                     if (fld[tx][ty]) continue;
     78                     que.push(make_pair(tx,ty));
     79                     fld[tx][ty]=true;
     80                 }
     81             }
     82         }
     83     }
     84     write(ans);
     85     putchar('\n');
     86 }
     87 
     88 int compress(int *x1, int *x2, int w)
     89 {
     90     vector<int> xs;
     91     for (int i=0; i<N; i++)
     92     {
     93         for (int d=-1; d<=1; d++)
     94         {
     95             int tx1=x1[i]+d, tx2=x2[i]+d;
     96             if (1<=tx1 && tx1<=w) xs.push_back(tx1);
     97             if (1<=tx2 && tx2<=w) xs.push_back(tx2);
     98         }
     99     }
    100     sort(xs.begin(),xs.end());
    101     xs.erase(unique(xs.begin(),xs.end()),xs.end());
    102     for (int i=0; i<N; i++)
    103     {
    104         x1[i]=find(xs.begin(), xs.end(), x1[i])-xs.begin();
    105         x2[i]=find(xs.begin(), xs.end(), x2[i])-xs.begin();
    106     }
    107     return xs.size();
    108 }

     

转载于:https://www.cnblogs.com/Ymir-TaoMee/p/9509630.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值