zoukankan      html  css  js  c++  java
  • Aizu 0531 "Paint Color" (坐标离散化+DFS or BFS)

    传送门

    题目描述:
        为了宣传信息竞赛,要在长方形的三合板上喷油漆来制作招牌。
        三合板上不需要涂色的部分预先贴好了护板。
        被护板隔开的区域要涂上不同的颜色,比如上图就应该涂上5种颜色。
        请编写一个程序计算涂色数量,输入数据中,保证看板不会被护板全部遮住,并且护板的边一定是水平或垂直的。
    
    Input
        第一个数是宽w(1 ≤ w ≤ 1000000);
        第二个数是高h(1 ≤ h ≤ 1000000)。
        第二行是护板的数量n(1 ≤ n ≤ 1000);
        接着n行是每个护板的左下角坐标 (x1 , y1 )和右上角坐标 (x2 , y2 ),用空格隔开: x1 , y1 , x2 , y2 (0 ≤ x1< x2 ≤ w, 0 ≤ y1 < y2 ≤ h 都是整数)
        招牌的坐标系左下角是 (0, 0) ,右上角是(w, h)
    Output
        颜色的数量
    中文题目描述

    中文题目描述摘抄自:https://blog.csdn.net/a1097304791/article/details/89707471

    参考资料:

      [1]:挑战程序设计竞赛(第二版)

    题解:

      坐标离散化+DFS求联通块个数;

      注意:需要的是联通空格的个数,转化的时候需要注意 < 右边界,而不能等于;

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define mem(a,b) memset(a,b,sizeof(a))
      4 #define ll long long
      5 const int maxn=1e3+50;
      6 
      7 int n;
      8 int w,h;
      9 bool vis[6*maxn][6*maxn];
     10 struct Point
     11 {
     12     int x,y;
     13 }p[maxn],f,e;
     14 int dx[4]={0,0,-1,1};
     15 int dy[4]={1,-1,0,0};
     16 vector<int >vs[2];
     17 
     18 int BS(int l,int r,int x,int val)
     19 {
     20     int mid=l+((r-l)>>1);
     21     while(vs[x][mid] != val)
     22     {
     23         if(vs[x][mid] > val)
     24             r=mid;
     25         else
     26             l=mid;
     27         mid=l+((r-l)>>1);
     28     }
     29     return mid;
     30 }
     31 void Compress()
     32 {
     33     vs[0].clear();
     34     vs[1].clear();
     35     for(int i=1;i <= 2*(n+1);++i)
     36     {
     37         for(int d=-1;d <= 1;++d)
     38         {
     39             vs[0].push_back(p[i].x+d);///离散化x
     40             vs[1].push_back(p[i].y+d);///离散化y
     41         }
     42     }
     43     sort(vs[0].begin(),vs[0].end());
     44     sort(vs[1].begin(),vs[1].end());
     45     vs[0].erase(unique(vs[0].begin(),vs[0].end()),vs[0].end());
     46     vs[1].erase(unique(vs[1].begin(),vs[1].end()),vs[1].end());
     47 
     48     for(int i=1;i <= 2*(n+1);++i)
     49     {
     50         p[i].x=BS(0,vs[0].size(),0,p[i].x);///手动二分查找
     51         p[i].y=BS(0,vs[1].size(),1,p[i].y);
     52 //        p[i].x=find(vs[0].begin(),vs[0].end(),p[i].x)-vs[0].begin();
     53 //        p[i].y=find(vs[1].begin(),vs[1].end(),p[i].y)-vs[1].begin();
     54     }
     55     f=p[2*n+1];
     56     e=p[2*n+2];
     57 }
     58 bool isSat(int x,int y)
     59 {
     60     return x >= f.x && x < e.x && y >= f.y && y < e.y;
     61 }
     62 void DFS(int x,int y)
     63 {
     64     vis[x][y]=true;
     65     for(int i=0;i < 4;++i)
     66     {
     67         int nexX=x+dx[i];
     68         int nexY=y+dy[i];
     69         if(!isSat(nexX,nexY) || vis[nexX][nexY])
     70             continue;
     71         DFS(nexX,nexY);
     72     }
     73 }
     74 ll Solve()
     75 {
     76     Compress();
     77     mem(vis,false);
     78     for(int k=1;k <= n;++k)
     79     {
     80         for(int i=p[k].x;i < p[k+n].x;++i)///严格小于右边界
     81             for(int j=p[k].y;j < p[k+n].y;++j)///严格小于右边界
     82                 vis[i][j]=true;
     83     }
     84     ll ans=0;
     85     for(int i=f.x;i < e.x;++i)///严格小于右边界
     86         for(int j=f.y;j < e.y;++j)///严格小于右边界
     87             if(!vis[i][j])
     88             {
     89                 ans++;
     90                 DFS(i,j);
     91             }
     92     return ans;
     93 }
     94 int main()
     95 {
     96 //    freopen("C:\Users\hyacinthLJP\Desktop\in&&out\contest","r",stdin);
     97     while(~scanf("%d%d",&w,&h) && w+h)
     98     {
     99         scanf("%d",&n);
    100         for(int i=1;i <= n;++i)
    101         {
    102             scanf("%d%d",&p[i].x,&p[i].y);
    103             scanf("%d%d",&p[i+n].x,&p[i+n].y);
    104         }
    105         p[2*n+1]=Point{0,0};
    106         p[2*n+2]=Point{w,h};
    107 
    108         printf("%lld
    ",Solve());
    109     }
    110     return 0;
    111 }
    View Code

    之所以做这道题,是因为省赛的时候,某题错解,用了离散化,按照书上写的find()函数,超时;

    自己手写了个二分,返回了其他错误;

    得出的结论是手写的二分 快于 find() 的时间复杂度;

    tel me why?????

  • 相关阅读:
    Linux虚拟内存管理(glibc)
    linux kernel内存回收机制
    Linux的Cache Memory(缓存内存)机制
    imx6用文件io操作gpio
    imx6中iomux IO复用
    start with git
    Linux进程的虚拟内存区域划分
    关于函数返回值为指针类型的分析
    对LCD接口的认识
    LCD屏背光驱动调试心得---血的教训
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/10872471.html
Copyright © 2011-2022 走看看