12171:Sculpture

Sculpture

思路:将三维空间网格化,每个长方体占据的所有单元标记为1。求面积的话,DFS所有的单元,依次检查是上下左右前后六个方向上相邻单元是否为1,若否则是表面,面积加+1。求体积的话,从外面某个单元开始DFS,求出外面值为0的单元的个数,那么总单元个数 - 外部值为0的单元个数 = 雕塑体积。但是由于外部单元个数巨大会导致堆栈溢出,所以需要对坐标进行离散化,另外应选BFS。

原来vjudge 有时本地运行OK单提交就编译错误是因为 #include<bits/stdc++.h> 有的库可能与变量名冲突。

#include<bits/stdc++.h>
using namespace std;
const int maxl = 30 + 5;
const int maxn = 50 + 5;
struct P{
    int x0,y0,z0;
    P(int a0=0,int b0=0,int c0=0):x0(a0),y0(b0),z0(c0){}
}Ps[maxn];
int T,n,volu,area;
int x0,y0,z0,x,y,z;
int V[maxl][maxl][maxl];
void process(){
    for(int i = 0;i < x;i++){
        for(int j = 0;j < y;j++){
            for(int k = 0;k < z;k++){
                V[x0+i][y0+j][z0+k] = 1;
            }
        }
    }
}
void dfs1(int x,int y,int z){
    volu++; V[x][y][z] = -1;
    for(int dx = -1;dx <= 1;dx++){
        for(int dy = -1;dy <= 1;dy++){
            for(int dz = -1;dz <= 1;dz++){
                if(!dx && !dy && !dz) continue;
                if(x+dx >= 0 && x+dx <maxl && y+dy >= 0 && y+dy < maxl
                    && z+dz >= 0 && z+dz < maxl && !V[x+dx][y+dy][z+dz]){
                    dfs1(x+dx,y+dy,z+dz);
                }
            }
        }
    }
}
void dfs2(int x,int y,int z){
    V[x][y][z] = -2;
    if(V[x][y][z+1] == -1) area++;
    if(V[x][y][z-1] == -1) area++;
    if(V[x][y+1][z] == -1) area++;
    if(V[x][y-1][z] == -1) area++;
    if(V[x+1][y][z] == -1) area++;
    if(V[x-1][y][z] == -1) area++;
    for(int dx = -1;dx <= 1;dx++){
        for(int dy = -1;dy <= 1;dy++){
            for(int dz = -1;dz <= 1;dz++){
                if(V[x+dx][y+dy][z+dz] == 1){
                    dfs2(x+dx,y+dy,z+dz);
                }
            }
        }
    }
}
int main(){
    // freopen("data.in","r",stdin);
    // freopen("data.out","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        volu = area = 0;
        memset(V,0,sizeof(V));
        for(int i = 0;i < n;i++){
            scanf("%d%d%d%d%d%d",&x0,&y0,&z0,&x,&y,&z);
            Ps[i] = P(x0,y0,z0);
            process();
        }
        dfs1(0,0,0);
        for(int i = 0;i < n;i++){
            P t = Ps[i];
            if(V[t.x0][t.y0][t.z0] == 1) dfs2(t.x0,t.y0,t.z0);
        }
        printf("%d %d\n",area,maxl*maxl*maxl - volu);
    }
    return 0;
}

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
const int maxc = 1000 + 5;
int T,n,area,volume,nx,ny,nz;
int x0[maxn],y0[maxn],z0[maxn],x1[maxn],y1[maxn],z1[maxn];
int xs[maxn],ys[maxn],zs[maxn];

int dx[] = { -1,1, 0,0, 0,0 };
int dy[] = {  0,0,-1,1, 0,0 };
int dz[] = {  0,0, 0,0,-1,1 };

int visit[maxn][maxn][maxn];

struct Cell{
    int x,y,z;
    Cell(int x = 0,int y = 0,int z = 0):x(x),y(y),z(z){};
    void setVis(){
        visit[x][y][z] = -1;
    }
    int inside(){
        return x >= 0 && x < nx-1 && y >= 0 && y < ny-1 && z >= 0 && z < nz-1;
    }
    int visited(){
        return visit[x][y][z] == -1;
    }
    int Solid(){
        return visit[x][y][z] == 1;
    }
    Cell near(int i){
        return Cell(x + dx[i],y + dy[i],z + dz[i]);
    }
    int volume(){
        return (xs[x+1]-xs[x])*(ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
    }
    int area(int i){
        if(dx[i]) return (ys[y+1]-ys[y])*(zs[z+1]-zs[z]);
        else if(dy[i]) return (xs[x+1]-xs[x])*(zs[z+1]-zs[z]);
        else return (xs[x+1]-xs[x])*(ys[y+1]-ys[y]);
    }
};
void floodFill(){
    Cell c;
    c.setVis();
    queue<Cell>q;
    q.push(c);
    while(!q.empty()){
        Cell c = q.front(); q.pop();
        volume += c.volume();
        for(int i = 0;i < 6;i++){
            Cell c2 = c.near(i);
            if(!c2.inside()) continue;
            if(c2.Solid()) area += c.area(i);
            else if(!c2.visited()){
                c2.setVis();
                q.push(c2);
            }
        }
    }
    volume = maxc*maxc*maxc - volume;
}

void discrete(int a[],int & n){
    sort(a,a + n);
    n = unique(a,a + n) - a;
}

int pos(int a[],int n,int x){
    return lower_bound(a,a + n,x) - a;
}

int main()
{
    // freopen("data.in","r",stdin);
    // freopen("data.out","w",stdout);
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        nx = ny = nz = 2;
        xs[0] = ys[0] = zs[0] = 0;
        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]);
            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];
        }
        discrete(xs,nx);
        discrete(ys,ny);
        discrete(zs,nz);
        memset(visit,0,sizeof(visit));
        for(int i = 0;i < n;i++){
            int sx = pos(xs,nx,x0[i]); int ex = pos(xs,nx,x1[i]);
            int sy = pos(ys,ny,y0[i]); int ey = pos(ys,ny,y1[i]);
            int sz = pos(zs,nz,z0[i]); int ez = pos(zs,nz,z1[i]);
            for(int j = sx;j < ex;j++){
                for(int k = sy;k < ey;k++){
                    for(int l = sz;l < ez;l++){
                        visit[j][k][l] = 1;
                    }
                }
            }
        }
        area = volume = 0;
        floodFill();
        printf("%d %d\n",area,volume);
    }
    return 0;
}

 

posted @ 2018-08-07 23:55  ACLJW  阅读(201)  评论(0编辑  收藏  举报