zoukankan      html  css  js  c++  java
  • Uva 12171 Sculpture

    题目连接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3323

    题意:

    三维空间中有n个长方体组成的雕塑,求表面积和体积。

    分析:

    因为长方体块可能在中间包围空气(也计入长方体体积),直接计算长方体体积是比较困难的,但是我们可以计算空气的体积,然后用总体积减去空气体积得出长方体的总体积。

    这道题网上很多答案是模糊不清并且提交上去是错误的。

    解这道题的关键是离散化后坐标的处理。在建立好离散坐标系后,利用离散坐标系在原坐标系中绘制长方体区域块,然后floodfill离散坐标系,初始点为(0,0,0)

    注意这里的关键,floodfill处理的是离散坐标系! 比如离散坐标(0,0,0),他是原始坐标也是(0,0,0)  为原点, 长方体第一个顶点的原始坐标为(2,4,6),处理后的离散坐标可能是(1,1,1)也可能是(1,1,2)等,这个不要紧,bfs时判断其是不是长方体的顶点原始坐标(看看该离散坐标对应的原始坐标区域有无被标记)就好了,然后累加空气块体积和长方体的表面积即可。

    附上一份网络上个人认为写得比较好的的参考代码:

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <queue>
      4 #include <cstring>
      5 using namespace std;
      6 
      7 const int maxn = 50 + 5;
      8 const int maxc = 1000 + 1;
      9 
     10 int n, x0[maxn], y0[maxn], z0[maxn], x1[maxn], y1[maxn], z1[maxn];
     11 
     12 int nx, ny, nz;
     13 int xs[maxn*2], ys[maxn*2], zs[maxn*2];
     14 
     15 const int dx[] = {1,-1,0,0,0,0};
     16 const int dy[] = {0,0,1,-1,0,0};
     17 const int dz[] = {0,0,0,0,1,-1};
     18 int color[maxn*2][maxn*2][maxn*2];
     19 
     20 struct Cell
     21 {
     22     int x, y, z;
     23     Cell(int x=0, int y=0, int z=0):x(x), y(y), z(z) {}
     24     bool valid() const { return x >= 0 && x < nx-1 && y >= 0 && y < ny-1 && z >= 0 && z < nz-1;}
     25     bool solid() const { return color[x][y][z] == 1; }
     26     bool getVis() const { return color[x][y][z] == 2; }
     27     void setVis() const { color[x][y][z] = 2; }
     28     Cell neighbor(int dir) const
     29     { return Cell(x+dx[dir], y+dy[dir], z+dz[dir]); }
     30     int volume()
     31     { return (xs[x+1]-xs[x]) * (ys[y+1]-ys[y]) * (zs[z+1]-zs[z]); }
     32     int area(int dir)
     33     {
     34         if(dx[dir]) return (ys[y+1]-ys[y]) * (zs[z+1]-zs[z]);
     35         if(dy[dir]) return (xs[x+1]-xs[x]) * (zs[z+1]-zs[z]);
     36         return (xs[x+1]-xs[x]) * (ys[y+1]-ys[y]);
     37     }
     38 };
     39 
     40 void discrectize(int* x, int& n)
     41 {
     42     sort(x, x + n);
     43     n = unique(x, x + n) - x;
     44 }
     45 
     46 int ID(int* x, int n, int x0)
     47 {
     48     return lower_bound(x, x + n, x0) - x;
     49 }
     50 
     51 void floodfill(int& v, int& s)
     52 {
     53     v = s = 0;
     54     Cell c;
     55     c.setVis();
     56     queue<Cell> q;
     57     q.push(c);
     58     while(!q.empty())
     59     {
     60         Cell c = q.front(); q.pop();
     61         v += c.volume();
     62         for(int i = 0; i < 6; ++i)
     63         {
     64             Cell c2 = c.neighbor(i);
     65             if(!c2.valid()) continue;
     66             if(c2.solid()) s += c.area(i);
     67             else if(!c2.getVis())
     68             {
     69                 c2.setVis();
     70                 q.push(c2);
     71             }
     72         }
     73     }
     74     v = maxc*maxc*maxc - v;
     75 }
     76 
     77 int main()
     78 {
     79     //freopen("in.txt", "r", stdin);
     80     int T;
     81     scanf("%d", &T);
     82     while(T--)
     83     {
     84         memset(color, 0, sizeof(color));
     85         nx = ny = nz = 2;
     86         xs[0] = ys[0] = zs[0] = 0;
     87         xs[1] = ys[1] = zs[1] = maxc;
     88         scanf("%d", &n);
     89         for(int i = 0; i < n; ++i)
     90         {
     91             scanf("%d%d%d%d%d%d", &x0[i], &y0[i], &z0[i], &x1[i], &y1[i], &z1[i]);
     92             x1[i] += x0[i]; y1[i] += y0[i]; z1[i] += z0[i];
     93             xs[nx++] = x0[i]; xs[nx++] = x1[i];
     94             ys[ny++] = y0[i]; ys[ny++] = y1[i];
     95             zs[nz++] = z0[i]; zs[nz++] = z1[i];
     96         }
     97         discrectize(xs, nx);
     98         discrectize(ys, ny);
     99         discrectize(zs, nz);
    100 
    101         for(int i = 0; i < n; ++i)
    102         {
    103             int X1 = ID(xs, nx, x0[i]), X2 = ID(xs, nx, x1[i]);
    104             int Y1 = ID(ys, ny, y0[i]), Y2 = ID(ys, ny, y1[i]);
    105             int Z1 = ID(zs, nz, z0[i]), Z2 = ID(zs, nz, z1[i]);
    106             for(int X = X1; X < X2; X++)
    107                 for(int Y = Y1; Y < Y2; ++Y)
    108                     for(int Z = Z1; Z < Z2; ++Z)
    109                         color[X][Y][Z] = 1;
    110         }
    111 
    112         int v, s;
    113         floodfill(v, s);
    114         printf("%d %d
    ", s, v);
    115     }
    116 
    117     return 0;
    118 }
  • 相关阅读:
    NBUT 1120 Reimu's Teleport (线段树)
    NBUT 1119 Patchouli's Books (STL应用)
    NBUT 1118 Marisa's Affair (排序统计,水)
    NBUT 1117 Kotiya's Incantation(字符输入处理)
    NBUT 1115 Cirno's Trick (水)
    NBUT 1114 Alice's Puppets(排序统计,水)
    188 Best Time to Buy and Sell Stock IV 买卖股票的最佳时机 IV
    187 Repeated DNA Sequences 重复的DNA序列
    179 Largest Number 把数组排成最大的数
    174 Dungeon Game 地下城游戏
  • 原文地址:https://www.cnblogs.com/seanliao/p/8031181.html
Copyright © 2011-2022 走看看