UVA

来源:互联网 发布:sublime text 3调试js 编辑:程序博客网 时间:2024/06/06 17:13
/*  A. 这题用到了之前做过的一些题的一些思想:    例如:    1. 之前做过的 UVA - 1103 Ancient Messages ( http://blog.csdn.net/mofushaohua_ln/article/details/78162277 )    两题十分相似之处在于,都是连通块问题,且都要在最外围,加上一圈“空气”,以使得所有空气格子得以连通    2. 之前做过的 UVA - 221 Urban Elevations ( http://blog.csdn.net/mofushaohua_ln/article/details/77799245 )    两题都用到了坐标离散化的思想,来减少所需单元格的数目  不过需要注意的是,floodfill时,运用离散化后的坐标来处理连通块,是没有问题的。但是,在统计表面积和体积时,一定要用原始坐标,否则必定WA    B. 该题主要思路见小白书 P172  不考虑雕塑本身,而考虑“空气”,在网格周围加一圈“空气”(目的时为了让所有空气格子连通),然后做一次 floodfill,即可得到空气的 “内表面积” 和体积,这个表面积就是雕塑的外表面积,雕塑体积等于总体积减去空气体积    floodfill 时直接使用离散化后的新坐标,但在统计表面积和体积时则需要使用原始坐标  */


#include <iostream>#include <algorithm>#include <queue>#include <cstring>#define rep(i, n) for ( int i = 0; i < (n); i++ )using namespace std;const int N = 50 + 5;const int C = 1e3 + 1;int n, x0[N], y0[N], z0[N], x1[N], y1[N], z1[N];// 离散化后的坐标int nx, ny, nz;int xs[N * 2], ys[N * 2], zs[N * 2];// 种子填充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[N * 2][N * 2][N * 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 neighbour (int dir) const{return Cell( x + dx[dir], y + dy[dir], z + dz[dir] );}int getVolume() const{return ( xs[x + 1] - xs[x] ) * ( ys[y + 1] - ys[y] ) * ( zs[z + 1] - zs[z] );}int getArea(int dir) const{if (dx[dir]) return ( ys[y + 1] - ys[y] ) * ( zs[z + 1] - zs[z] );if (dy[dir]) 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 = s = 0;Cell c;c.setVis();queue<Cell> q;q.push(c);while (!q.empty()){Cell c = q.front();q.pop();v += c.getVolume();rep(i, 6){Cell c2 = c.neighbour(i);if (!c2.valid()) continue;if (c2.solid()) s += c.getArea(i);else if (!c2.getVis()){c2.setVis();q.push(c2);}}}v = C * C * C- v;}int main(){int t;cin >> t;while (t--){nx = ny = nz = 2;xs[0] = ys[0] = zs[0] = 0;xs[1] = ys[1] = zs[1] = C;cin >> n;rep(i, n){cin >> 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);// paintmemset( color, 0, sizeof(color) );rep(i, n){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);cout << s << " " << v << endl;}}

原创粉丝点击