zoukankan      html  css  js  c++  java
  • 离散化方法

    个人笔记,仅供复习

    1.概念:离散化就是把无限空间的有限个体映射到有限空间去,从而大幅节省空间或时间。基本思想就是在众多可能的情况中“只考虑我需要用的值”

    2.适用范围:除了对于较大整数需要使用离散化之外,对于一些需要使用整型数据结构,但给出的数据却是小数的也可以使用离散化,将其索引为整数就可以了。

    3.一般步奏:

    • 排序
    • 去重
    • 建立索引

    4.例题:Uva12171

    // UVa12171 Sculpture
    // Rujia Liu
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 50 + 5;
    const int maxc = 1000 + 1;
    
    // original data
    int n, x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
    
    // discretization related
    int nx, ny, nz;
    int xs[maxn*2], ys[maxn*2], zs[maxn*2];
    
    // floodfill related
    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};
    int color[maxn*2][maxn*2][maxn*2];
    
    struct Cell {
      int x, y, z;
      Cell(int x=0, int y=0, int z=0):x(x),y(y),z(z){}
      bool valid() const {
        return x >= 0 && x < nx-1 && y >= 0 && y < ny-1 && z >= 0 && z < nz-1;
      }
      bool solid() const {
        return color[x][y][z] == 1; // solid
      }
      bool getVis() const {
        return color[x][y][z] == 2; // visited
      }
      void setVis() const {
        color[x][y][z] = 2;
      }
      Cell neighbor(int dir) const {
        return Cell(x+dx[dir], y+dy[dir], z+dz[dir]);
      }
      int volume() const {
        return (xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
      }
      int area(int dir) const {
        if(dx[dir] != 0) return (ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
        else if(dy[dir] != 0) return (xs[x+1]-xs[x])*(zs[z+1]-zs[z]);
        return (xs[x+1]-xs[x])*(ys[y+1]-ys[y]);
      }
    };
    
    void discretize(int* x, int& n) {
      sort(x, x+n);
      n = unique(x, x+n) - x;
    }
    
    int ID(int* x, int n, int x0) {
      return lower_bound(x, x + n, x0) - x;
    }
    
    void floodfill(int& v, int& s) {
      v = 0;
      s = 0;
      Cell c;
      c.setVis();
      queue<Cell> q;
      q.push(c);
      while(!q.empty()) {
        Cell c = q.front(); q.pop();
        v += c.volume();
        for(int i = 0; i < 6; i++) {
          Cell c2 = c.neighbor(i);
          if(!c2.valid()) continue;
          if(c2.solid()) s += c.area(i);
          else if(!c2.getVis()){
            c2.setVis();
            q.push(c2);
          }
        }
      }
      v = maxc*maxc*maxc - v;
    }
    
    int main() {
      int T;
      scanf("%d", &T);
      while(T--) {
        nx = ny = nz = 2;
        xs[0] = ys[0] = zs[0] = 0;
        xs[1] = ys[1] = zs[1] = maxc;
        scanf("%d", &n);
        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]);
          x1[i] += x0[i]; y1[i] += y0[i]; z1[i] += z0[i];
          xs[nx++] = x0[i]; xs[nx++] = x1[i];
          ys[ny++] = y0[i]; ys[ny++] = y1[i];
          zs[nz++] = z0[i]; zs[nz++] = z1[i];
        }
        discretize(xs, nx);
        discretize(ys, ny);
        discretize(zs, nz);
    
        // paint
        memset(color, 0, sizeof(color));
        for(int i = 0; i < n; i++) {
          int X1 = ID(xs, nx, x0[i]), X2 = ID(xs, nx, x1[i]);
          int Y1 = ID(ys, ny, y0[i]), Y2 = ID(ys, ny, y1[i]);
          int Z1 = ID(zs, nz, z0[i]), Z2 = ID(zs, nz, z1[i]);
          for(int X = X1; X < X2; X++)
            for(int Y = Y1; Y < Y2; Y++)
              for(int Z = Z1; Z < Z2; Z++)
                color[X][Y][Z] = 1;
        }
    
        int v, s;
        floodfill(v, s);
        printf("%d %d
    ", s, v);
      }
    
      return 0;
    }

  • 相关阅读:
    C#类中的字段、属性和方法
    Linux下制作Windows启动U盘的工具
    将samba共享目录映射为本地文件夹(百度网盘直接下载到samba共享目录下)
    《怎样编写研究报告》读书笔记0-0
    mcnp的重复探测器单元计数-fmesh卡的介绍
    单能X射线产生方法
    matlab学习之降噪平滑算法
    matlab学习之求解函数的根和极小值
    matlab学习之绘制参数曲线,添加辅助线以及颜色设置
    MC资源整理
  • 原文地址:https://www.cnblogs.com/long98/p/10352243.html
Copyright © 2011-2022 走看看