题意:
在100*100*100的三维空间内,给出若干食物的坐标,如果一段空间被食物包围着,那么这段空间就成为一个洞,求洞的数目
思路:
对每一个不是食物的点做bfs的Flood Fill即可。(还有一种方法是对每一个是食物的点做dfs的Flood Fill,不过想想看如果是2,2,2到99,99,99是一个洞的话,这个洞的表面积,大约100*100*6 = 60000,爆栈吧,没尝试过)
代码:
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define N 105
int ix, ax, iy, ay, iz, az;
bool f[N][N][N];
struct P
{
int x, y, z;
P() {}
P(int _x, int _y, int _z): x(_x), y(_y), z(_z) {}
P operator + (const P &p) { return P(x+p.x, y+p.y, z+p.z); }
bool legal() { return x>=ix&&x<=ax && y>=iy&&y<=ay && z>=iz&&z<=az; }
bool hole() { return !f[x][y][z]; }
void setF() { f[x][y][z] = true; }
};
P cur, nxt;
P d[6] = {P(1,0,0),P(-1,0,0),P(0,1,0),P(0,-1,0),P(0,0,1),P(0,0,-1)};
int ans;
void flood_fill(int x, int y, int z)
{
f[x][y][z] = true;
queue <P> Q;
Q.push(P(x,y,z));
bool flag = true;
while (!Q.empty())
{
cur = Q.front();
Q.pop();
for (int i = 0; i < 6; ++ i)
{
nxt = cur + d[i];
if (!nxt.legal()) flag = false;
else if (nxt.hole())
{
nxt.setF();
Q.push(nxt);
}
}
}
if (flag) ans ++;
}
void work()
{
for (int i = ix; i <= ax; ++ i)
for (int j = iy; j <= ay; ++ j)
for (int k = iz; k <= az; ++ k)
if (!f[i][j][k])
flood_fill(i,j,k);
}
int main()
{
int t, n, x, y, z;
scanf("%d", &t);
while (t --)
{
memset(f, false, sizeof(f));
ans = 0;
ix = iy = iz = 100;
ax = ay = az = 1;
scanf("%d", &n);
while (n --)
{
scanf("%d %d %d", &x, &y, &z);
if (x > ax) ax = x; if (x < ix) ix = x;
if (y > ay) ay = y; if (y < iy) iy = y;
if (z > az) az = z; if (z < iz) iz = z;
f[x][y][z] = true;
}
work();
printf("%d\n", ans);
}
}