题目链接如下:
这道题我开始的解法是很笨拙的,小数据上结果是对的,但OJ上提交一直显示编译错误,到现在我还不知道错在哪……后来参考了 hdu 2771(uva 12171) Sculpture bfs+离散化-CSDN博客 这里的解法,这个解法应该是参考了刘汝佳的解法。离散化对我来说是比较陌生的概念,还学习了一下unique的用法(sort之后unique,指向不重复的数据的下一个位置)。
我最后的代码如下:
#include <cstdio>
#include <algorithm>
#include <deque>
#include <vector>
const int maxx = 1005;
// #define debug
struct node{
int x, y, z;
node(int _x, int _y, int _z): x(_x), y(_y), z(_z){}
};
struct box{
int x0, y0, z0, x, y, z;
box(int _x0, int _y0, int _z0, int _x, int _y, int _z): x0(_x0), y0(_y0), z0(_z0), x(_x), y(_y), z(_z){}
};
int T, n, x0, y0, z0, x, y, z, nx, ny, nz, area, vol, totVol;
int cube[101][101][101];
int dx[] = {-1, 1, 0, 0, 0, 0};
int dy[] = {0, 0, 1, -1, 0, 0};
int dz[] = {0, 0, 0, 0, 1, -1};
std::vector<box> boxVec;
std::vector<int> xVec, yVec, zVec;
void reset(){
for (int i = 0; i < 101; ++i){
for (int j = 0; j < 101; ++j){
for (int k = 0; k < 101; ++k){
cube[i][j][k] = 0;
}
}
}
}
void discretize(std::vector<int> &vec, int &n){
sort(vec.begin(), vec.end());
n = std::unique(vec.begin(), vec.end()) - vec.begin();
}
int id(std::vector<int> &vec, int k){
return find(vec.begin(), vec.end(), k) - vec.begin();
}
void floodfill(int i, int j, int k){
std::deque<node> dq;
cube[i][j][k] = -1;
dq.push_back(node(i, j, k));
while (!dq.empty()){
node temp = dq.front();
dq.pop_front();
i = temp.x;
j = temp.y;
k = temp.z;
vol += (xVec[i + 1] - xVec[i]) * (yVec[j + 1] - yVec[j]) * (zVec[k + 1] - zVec[k]);
for (int u = 0; u < 6; ++u){
if (i + dx[u] >= 0 && i + dx[u] <= 100 && j + dy[u] >= 0 && j + dy[u] <= 100 && k + dz[u] >= 0 && k + dz[u] <= 100 && cube[i + dx[u]][j + dy[u]][k + dz[u]] == 1){
if (dx[u]){
area += (yVec[j + 1] - yVec[j]) * (zVec[k + 1] - zVec[k]);
} else if (dy[u]){
area += (xVec[i + 1] - xVec[i]) * (zVec[k + 1] - zVec[k]);
} else if (dz[u]){
area += (xVec[i + 1] - xVec[i]) * (yVec[j + 1] - yVec[j]);
}
}
}
for (int u = 0; u < 6; ++u){
if (i + dx[u] >= 0 && i + dx[u] < nx - 1 && j + dy[u] >= 0 && j + dy[u] < ny - 1 && k + dz[u] >= 0 && k + dz[u] < nz - 1 && cube[i + dx[u]][j + dy[u]][k + dz[u]] == 0){
cube[i + dx[u]][j + dy[u]][k + dz[u]] = -1;
dq.push_back(node(i + dx[u], j + dy[u], k + dz[u]));
}
}
}
}
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
scanf("%d", &T);
totVol = maxx * maxx * maxx;
while (T--){
scanf("%d", &n);
if (n == 0){
printf("0 0\n");
continue;
}
boxVec.clear();
xVec.clear();
yVec.clear();
zVec.clear();
xVec.push_back(0);
xVec.push_back(maxx);
yVec.push_back(0);
yVec.push_back(maxx);
zVec.push_back(0);
zVec.push_back(maxx);
area = vol = 0;
for (int l = 0; l < n; ++l){
scanf("%d %d %d %d %d %d", &x0, &y0, &z0, &x, &y, &z);
boxVec.push_back(box(x0, y0, z0, x0 + x, y0 + y, z0 + z));
xVec.push_back(x0);
xVec.push_back(x0 + x);
yVec.push_back(y0);
yVec.push_back(y0 + y);
zVec.push_back(z0);
zVec.push_back(z0 + z);
}
discretize(xVec, nx);
discretize(yVec, ny);
discretize(zVec, nz);
for (int l = 0; l < n; ++l){
for (int i = id(xVec, boxVec[l].x0); i < id(xVec, boxVec[l].x); ++i){
for (int j = id(yVec, boxVec[l].y0); j < id(yVec, boxVec[l].y); ++j){
for (int k = id(zVec, boxVec[l].z0); k < id(zVec, boxVec[l].z); ++k){
cube[i][j][k] = 1;
}
}
}
}
floodfill(0, 0, 0);
printf("%d %d\n", area, totVol - vol);
reset();
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
我原先的解法如下(oj上有编译错误....小数据没错):
#include <cstdio>
#include <algorithm>
#include <deque>
const int maxx = 1005;
// #define debug
struct node{
int x, y, z;
node(int _x, int _y, int _z): x(_x), y(_y), z(_z){}
};
int T, n, x0, y0, z0, x, y, z, minX, minY, minZ, maxX, maxY, maxZ, area, vol;
int cube[maxx][maxx][maxx];
int dx[] = {-1, 1, 0, 0, 0, 0};
int dy[] = {0, 0, 1, -1, 0, 0};
int dz[] = {0, 0, 0, 0, 1, -1};
void reset(){
for (int i = minX; i <= maxX; ++i){
for (int j = minY; j <= maxY; ++j){
for (int k = minZ; k <= maxZ; ++k){
cube[i][j][k] = 0;
}
}
}
}
int main(){
#ifdef debug
freopen("0.txt", "r", stdin);
freopen("1.txt", "w", stdout);
#endif
scanf("%d", &T);
while (T--){
scanf("%d", &n);
if (n == 0){
printf("0 0\n");
continue;
}
minX = minY = minZ = maxx - 1;
maxX = maxY = maxZ = 0;
area = vol = 0;
for (int l = 0; l < n; ++l){
scanf("%d %d %d %d %d %d", &x0, &y0, &z0, &x, &y, &z);
minX = std::min(minX, x0 - 1);
minY = std::min(minY, y0 - 1);
minZ = std::min(minZ, z0 - 1);
maxX = std::max(maxX, x0 + x + 1);
maxY = std::max(maxY, y0 + y + 1);
maxZ = std::max(maxZ, z0 + z + 1);
for (int i = x0; i < x0 + x; ++i){
for (int j = y0; j < y0 + y; ++j){
for (int k = z0; k < z0 + z; ++k){
cube[i][j][k] = 1;
}
}
}
}
std::deque<node> dq;
cube[minX][minY][minZ] = -1;
dq.push_back(node(minX, minY, minZ));
while (!dq.empty()){
node temp = dq.front();
dq.pop_front();
for (int u = 0; u < 6; ++u){
int xx = temp.x + dx[u];
int yy = temp.y + dy[u];
int zz = temp.z + dz[u];
if (xx >= minX && xx <= maxX && yy >= minY && yy <= maxY && zz >= minZ && zz <= maxZ && !cube[xx][yy][zz]){
cube[xx][yy][zz] = -1;
dq.push_back(node(xx, yy, zz));
}
}
}
for (int i = minX; i <= maxX; ++i){
for (int j = minY; j <= maxY; ++j){
for (int k = minZ; k <= maxZ; ++k){
if (!cube[i][j][k]){
cube[i][j][k] = 1;
}
if (cube[i][j][k] == 1){
vol++;
}
}
}
}
for (int i = minX; i <= maxX; ++i){
for (int j = minY; j <= maxY; ++j){
for (int k = minZ; k <= maxZ; ++k){
if (cube[i][j][k] == 1){
if (i - 1 >= minX && cube[i - 1][j][k] == -1){
area++;
}
if (j - 1 >= minY && cube[i][j - 1][k] == -1){
area++;
}
if (k - 1 >= minZ && cube[i][j][k - 1] == -1){
area++;
}
if (i + 1 <= maxX && cube[i + 1][j][k] == -1){
area++;
}
if (j + 1 <= maxY && cube[i][j + 1][k] == -1){
area++;
}
if (k + 1 <= maxZ && cube[i][j][k + 1] == -1){
area++;
}
}
}
}
}
printf("%d %d\n", area, vol);
reset();
}
#ifdef debug
fclose(stdin);
fclose(stdout);
#endif
return 0;
}