您的位置:首页 > 其它

UVa12171 Sculpture

2015-10-02 16:39 274 查看
题目大意:给定一些长方体的坐标,求这些长方体组成的空间的外表面积和体积(注意被包在内部的也算体积)

思路:把这些长方体放在一个1001*1001*1001的空间中,然后从外面对空的格子进行floodfill。每次遇到一个被标记的方块就加上接触面的面积

#include <bits/stdc++.h>
#define DEBUG(x) cerr<<"line:"<<__LINE__<<", "<<#x" == "<<(x)<<endl;
#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)
#define FOR(it,s) for(__typeof(s.begin()) it=s.begin();it!=s.end();it++)
#define ALL(a) (a).begin(),(a).end()
#define RALL(x) (a).rbegin(),(a).rend()
#define RI(x) scanf("%d",&(x))
#define RII(x,y) scanf("%d%d",&(x),&(y))
#define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
#define DRI(x) int (x);scanf("%d",&(x))
#define DRII(x,y) int (x),(y);scanf("%d%d",&(x),&(y))
#define DRIII(x,y,z) int (x),(y),(z);scanf("%d%d%d",&(x),&(y),&(z))
#define MS0(a) memset((a),0,sizeof((a)))
#define MS1(a) memset((a),-1,sizeof((a)))
#define MS(a,b) memset((a),(b),sizeof((a)))
#define PB push_back
#define SZ(a) (int)(a).size()

using namespace std;

typedef long long LL;
typedef unsigned int uint;
typedef unsigned long long ULL;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<vi> vvi;

#define INF 1000000000
const double eps = 1e-10;
int dcmp(double x){
if(fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
// ------------------
// author : onehrxn
// ------------------
struct node{
int x, y, z;
node(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z){}
};
struct cell{
LL lx, ly, lz;
bool c;
cell(LL lx=0,LL ly=0, LL lz=0,bool c =0):lx(lx),ly(ly),lz(lz),c(c){}
LL vol(){
return (LL)lx * (LL)ly * (LL)lz;
}
LL area(int dir){
// up down left right forward backward
switch(dir){
case 0:
case 1: return ly * lx; break;
case 2:
case 3: return lx * lz; break;
case 4:
case 5: return ly * lz; break;
}
}
};
map<LL, int> IDx, IDy, IDz;
map<int,LL> ox, oy, oz;
const int maxn = 100 + 10;
cell m[maxn][maxn][maxn];
bool vis[maxn][maxn][maxn];
LL x[maxn], ax[maxn], y[maxn], ay[maxn], z[maxn], az[maxn];
// up down left right forward backward
const int dx[] = {0, 0, 0, 0, -1, 1};
const int dy[] = {0, 0, -1, 1, 0, 0};
const int dz[] = {1, -1, 0, 0, 0, 0};
int N;
LL resv, resa;
int cntx, cnty, cntz;
inline void init(void);
int v(int idx, int idy, int idz); // return v
inline void set_block(int cur); // set the block to black
inline void w_flood(void);// find the white block and dfs,return area and v
inline bool ok(int newx, int newy, int newz);
inline void calc_block(void);
int main(void)
{
//ios::sync_with_stdio(false);
//cin.tie(0);
#ifdef LOCAL
//freopen("input", "r", stdin);
//freopen("output", "w", stdout);
#endif
DRI(T);
while(T--){
RI(N);
init();
set<LL> sx, sy, sz;
sx.insert(0); sy.insert(0); sz.insert(0);
sx.insert(1001);sy.insert(1001);sz.insert(1001);

for(int i = 0; i < N; i++) {
scanf("%lld %lld %lld", &x[i], &y[i], &z[i]);
scanf("%lld %lld %lld", &ax[i], &ay[i], &az[i]);

sx.insert(x[i]); sx.insert(x[i] + ax[i]);
sy.insert(y[i]); sy.insert(y[i] + ay[i]);
sz.insert(z[i]); sz.insert(z[i] + az[i]);
}
cntx = 0, cnty = 0, cntz = 0;
FOR(it, sx) {IDx[*it] = cntx++; ox[cntx-1] = *it;/*printf("%lld: %d\n",*it,IDx[*it]);*/}
FOR(it, sy) {IDy[*it] = cnty++; oy[cnty-1] = *it;/*printf("%lld: %d\n",*it,IDy[*it]);*/}
FOR(it, sz) {IDz[*it] = cntz++; oz[cntz-1] = *it;/*printf("%lld: %d\n",*it,IDz[*it]);*/}

calc_block();

// set all the inside box to
for(int i = 0; i < N; i++) {
set_block(i);
}

// bfs from the white
w_flood();
printf("%lld %lld\n", resa, resv);
}

#ifdef LOCAL
cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
return 0;
}

inline void calc_block(void){
for(int i = 0; i <= cntx - 2; i++){
for(int j = 0; j <= cnty - 2; j++){
for(int k = 0; k <= cntz - 2; k++){
m[i][j][k].lx = abs(ox[i+1] - ox[i]);
m[i][j][k].ly = abs(oy[j+1] - oy[j]);
m[i][j][k].lz = abs(oz[k+1] - oz[k]);
}
}
}
}

void init(void){
IDx.clear();IDy.clear(); IDz.clear();
ox.clear(); oy.clear(); oz.clear();
MS0(vis);
for(int i = 0; i <= cntx; i++){
for(int j = 0; j <= cnty; j++) {
for(int k = 0; k <= cntz; k++) {
m[i][j][k].c = 0;
}
}
}
resv = resa = INF;
}

inline void set_block(int cur){

for(int curx = IDx[x[cur]]; curx <= IDx[x[cur]+ax[cur]]-1; curx++)
for(int cury = IDy[y[cur]]; cury <= IDy[y[cur]+ay[cur]]-1; cury++)
for(int curz = IDz[z[cur]]; curz <= IDz[z[cur]+az[cur]]-1; curz++){
m[curx][cury][curz].c = 1;
vis[curx][cury][curz] = 1;
}
}

inline void w_flood(void){
// start from the outside face
queue<node> q;
q.push(node(0,0,0));
vis[0][0][0] = 1;
// search
LL nowv = 0;
resa = 0; resv = 0;
while(!q.empty()){

node nn = q.front(); q.pop();
if(!ok(nn.x, nn.y, nn.z)) continue;
if(m[nn.x][nn.y][nn.z].c == 1) continue;

// update nowv
nowv += m[nn.x][nn.y][nn.z].vol();

for(int dir = 0; dir < 6; dir++){
int newx = nn.x + dx[dir], newy = nn.y + dy[dir], newz = nn.z + dz[dir];
if(!ok(newx, newy, newz)) {
continue;
}
if(ok(newx, newy, newz)){
if(m[newx][newy][newz].c == 0){
if(!vis[newx][newy][newz]) {
q.push(node(newx, newy, newz));
vis[newx][newy][newz] = 1;
}
}
else{ // meet the black
resa += m[newx][newy][newz].area(dir);
}
}
}
}
resv = 1001*1001*1001 - nowv;
}

inline bool ok(int x, int y, int z){
if(x < 0 || x > (cntx - 2)) return 0;
if(y < 0 || y > (cnty - 2)) return 0;
if(z < 0 || z > (cntz - 2)) return 0;
return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM