P5229 [AHOI2013] 立方体

题意

给出 \(n\) 个立方体,求由祂们组成的几何图形的表面积。
\(n,x,y,z\le200\)

思路

直接跑扫描线是不行的,因为那样会把内表面也算进去,考虑用一些更暴力的方法。
先用三维差分求出每个位置是否被立方体占据。然后从 \((0,0,0)\) 开始宽搜,不能穿过被占据的位置。如果遇到一个被占据的位置,就给答案 \(+1\)
时间复杂度 \(\mathcal O(n^3)\)

代码

// Problem: P5229 [AHOI2013] 立方体
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P5229
// Memory Limit: 125 MB
// Time Limit: 700 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T&x){
        x=0;char c=getchar();bool f=0;
        while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        f?x=-x:0;
    }
    template<typename T>
    inline void write(T x){
        if(x==0){putchar('0');return ;}
        x<0?x=-x,putchar('-'):0;short st[50],top=0;
        while(x) st[++top]=x%10,x/=10;
        while(top) putchar(st[top--]+'0');
    }
    inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
    inline void write(char c){putchar(c);}
    inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
    inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
    template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
    template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
    template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
const int maxn=210;
int n,hv[maxn][maxn][maxn];
int fx[10]={0,0,0,0,0,1,-1};
int fy[10]={0,0,0,1,-1};
int fz[10]={0,1,-1};
queue<tuple<int,int,int>>q;
bool flag[maxn][maxn][maxn];
signed main(){
    read(n);
    for(int i=1;i<=n;i++){
        int x,y,z,xx,yy,zz;read(x,y,z,xx,yy,zz);
        x++,y++,z++;
        hv[x][y][z]++;
        hv[xx+1][y][z]--,hv[x][yy+1][z]--,hv[x][y][zz+1]--;
        hv[xx+1][yy+1][z]++,hv[xx+1][y][zz+1]++,hv[x][yy+1][zz+1]++;
        hv[xx+1][yy+1][zz+1]--;
    }
    for(int i=1;i<=202;i++) for(int j=1;j<=202;j++) for(int k=1;k<=202;k++){
        hv[i][j][k]+=hv[i-1][j][k]+hv[i][j-1][k]+hv[i][j][k-1];
        hv[i][j][k]-=hv[i-1][j-1][k]+hv[i-1][j][k-1]+hv[i][j-1][k-1];
        hv[i][j][k]+=hv[i-1][j-1][k-1];
    }
    q.push({0,0,0});flag[0][0][0]=1;
    int ans=0;
    while(!q.empty()){
        auto[x,y,z]=q.front();q.pop();
        for(int i=1;i<=6;i++){
            int xx=x+fx[i],yy=y+fy[i],zz=z+fz[i];
            if(xx<0||yy<0||zz<0||xx>202||yy>202||zz>202) continue;
            if(flag[xx][yy][zz]) continue;
            if(hv[xx][yy][zz]) ans++;
            else q.push({xx,yy,zz}),flag[xx][yy][zz]=1;
        }
    }
    write(ans);
    return 0;
}
posted @ 2026-06-01 17:14  Link-Cut_Trees  阅读(11)  评论(0)    收藏  举报