zoukankan      html  css  js  c++  java
  • UVA 12171 (hdu 2771)sculptrue(离散化)

    以前对离散化的理解不够,所以把端点和区间区分来考虑但是做完这题以后有了新的认识:

    先来看一个问题:给你以下的网格,你需要多少空间去存储红点区间的信息呢?

    只需要图上所示的1,2,3,4个点就足够表示红点所在区间了,为什么不是一个区间的第一个红点和最后一个红点呢?(如果这样记录的话则必须加一区间点,记录区间内部信息,因为端点可能是两个区间的交集而区间内可能只被操作了一次)这样做的好处是空白区域的长度也能轻易计算出来。

    因此离散化的核心在于以点代表区间

    为了计算总区间两端空白的长度,增加A和B点。

    原数据找离散后的值直接二分,没必要建map,因为map的查询也是logN级别的

    知道了这些,存储问题就解决了。

    /*
    Created by Rey Chen on 2015.6.25
    */

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    //#define local
    using namespace std;
    const int maxn = 50 + 1;
    const int max2n = 100 + 2;
    const int maxc = 1000 + 1;//coordinate;
    typedef int ll;
    // original data
    int n, x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
    // discretized data
    int xs[max2n], ys[max2n], zs[max2n];
    int xn, yn, zn;//the numbers of each coordinate
    
    //1 means solid, 2 means visited air
    int color[max2n][max2n][max2n];
    
    
    void discretize(int* x, int& n) {
      sort(x, x+n);
      n = unique(x, x+n) - x;
    }
    
    struct Cell
    {
       int x, y, z;
       Cell(int x,int y,int z):x(x),y(y),z(z){}
    };
    //related to flood fill
    const int dx[] = {1,-1,0,0,0,0};
    const int dy[] = {0,0,1,-1,0,0};
    const int dz[] = {0,0,0,0,1,-1};
    
    #define vis(u) (color[v.x][v.y][v.z] == 2)
    #define setVis(u) color[u.x][u.y][u.z] = 2//solid..
    #define uNeigh(i) Cell v(u.x+dx[i], u.y+dy[i], u.z+dz[i])
    #define inside(v) (v.x >=0 && v.x < xn && v.y >= 0 && v.y < yn && v.z >= 0 && v.z < zn)
    #define issolid(v) (color[v.x][v.y][v.z] == 1)
    #define dis(u,x) (x##s[u.x+1]-x##s[u.x])
    #define vol(u) (ll)(xs[u.x+1]-xs[u.x])*(ys[u.y+1]-ys[u.y])*(zs[u.z+1]-zs[u.z])//为了让原本最后一层空气计算时不下标不越界 还要再加一层
    
    inline ll area(Cell& v, int dir){
       if(dx[dir]) return (ll)dis(v,y)*dis(v,z);
       if(dy[dir]) return (ll)dis(v,x)*dis(v,z);
       return (ll)dis(v,x)*dis(v,y);
    }
    
    //dfs might stack overflow
    void floodfill(ll &V,ll &s)
    {
       queue<Cell> q;
       Cell u(0,0,0);// Cell u = Cell() 1,2
       setVis(u);
       q.push(u);
       V = s = 0;
       while(!q.empty()) {
          u = q.front();q.pop();
          V += vol(u); //calculate air volume
          for(int i = 0; i < 6; i++) {
             uNeigh(i);
             if(!inside(v)) continue;//最后一层不加
             if(issolid(v)) s += area(v,i); //ensure air vis once meet solid add area
             else if(!vis(v)) {
                setVis(v);
                q.push(v);
             }
          }
       }
       V = maxc*maxc*maxc - V;
    }
    
    #define add(x) x##1[i] += x##0[i]
    #define dadd(a) xs[t] = x##a[i]; ys[t] = y##a[i]; zs[t++] = z##a[i]
    #define ID(x,n,val) (lower_bound(x,x+n,val) - x)
    #define GetId(X,x) X##0 = ID(x##s, x##n, x##0[i]);X##1 = ID(x##s, x##n, x##1[i])
    //X0 = ID(xs,xn,x0[i]);
    int main()
    {
    #ifdef local
        freopen("in.txt","r",stdin);
    #endif // local
    
       int T;
       scanf("%d",&T);
       while(T--) {
          scanf("%d",&n); int t = 2;
          *xs = *ys = *zs = 0;//add air 
          xs[1] = ys[1] = zs[1] = maxc;//最后面有两层空气
          for(int i = 0; i < n; i++) {
             scanf("%d%d%d%d%d%d", x0+i, y0+i, z0+i, x1+i, y1+i, z1+i);
             add(x);add(y);add(z);
             dadd(0); dadd(1);
          }
          xn = yn = zn = t ;
          discretize(xs,xn);
          discretize(ys,yn);
          discretize(zs,zn);
          xn--;yn--;zn--;//不访问最后一层空气,计算总体积时要加上最后一层空气
    
          memset(color,0,sizeof(color));
          for(int i = 0; i < n; i++) { //solid set
             int X0, X1, Y0, Y1, Z0, Z1;
             GetId(X,x); GetId(Y,y); GetId(Z,z);
             for(int X = X0; X < X1; X++)
                for(int Y = Y0; Y < Y1; Y++)
                   for(int Z = Z0; Z < Z1; Z++)
                      color[X][Y][Z] = 1;
          }
          ll v,s;
          floodfill(v,s);
          printf("%d %d
    ",s,v);
       }
       return 0;
    }
  • 相关阅读:
    Windows 下Npm和NodeJS升级
    解决本地端口占用问题
    eclipse spring boot项目部署
    JPA 使用 Specification 复杂查询和 Criteria 查询
    datepicker 属性设置 以及方法和事件
    sqlServer拼结列字符串
    Gson基本操作,JsonObject,JsonArray,String,JavaBean,List互转
    PNChart,简洁高效有动画效果的iOS图表库
    PureLayout,使用纯代码写AutoLayout
    iRate快速绕坑使用
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4599388.html
Copyright © 2011-2022 走看看