三维空间上的BFS。(不是自己想出来的,思路是讨论区@TLE from SMIE 同学的。)
需要注意的地方:1.hole不一定是一个点,注意到关键词:continuous ,它可以是任意形状的,只要六个方向都被围住即可。 2.一定要考虑到边界,即"hole"若有一部分是边界,那它便不是hole。
代码如下:
#include <iostream>
#include <string>
using namespace std;
bool grap[101][101][101];//三维空间
//每一个case的边界
int min_x,min_y,min_z;
int max_x,max_y,max_z;
void reset()
{
min_x = min_y = min_z = 100;
max_x = max_y = max_z = 1;
for (int i = 1;i <= 100;i ++)
for (int j = 1;j <= 100;j ++)
for (int k = 1;k <= 100;k ++)
grap[i][j][k] = 0;
}
void init(int m)
{
reset();
int x,y,z;
for (int i = 0;i < m;i ++)
{
cin >> x >> y >> z;
grap[x][y][z] = 1;
//更新边界
min_x = min(x,min_x); max_x = max(x,max_x);
min_y = min(y,min_y); max_y = max(y,max_y);
min_z = min(z,min_z); max_z = max(z,max_z);
}
}
bool is_side(int x,int y,int z) //判断该点是否为边界点
{
if (x == min_x || x == max_x || y == min_y || y == max_y
|| z == min_z || z == max_z)
return true;
return false;
}
bool bfs(int x,int y,int z)
{
if (grap[x][y][z] == 1) return true; //如果是food cube或者被处理过的"hole"点,返回true
if (is_side(x,y,z)) return false; //如果是边界点,返回false
grap[x][y][z] = 1; //将hole点标记为1,表示已处理过
bool pd = true;
//遍历上下左右前后
pd &= bfs(x,y,z + 1);
pd &= bfs(x,y,z - 1);
pd &= bfs(x - 1,y,z);
pd &= bfs(x + 1,y,z);
pd &= bfs(x,y + 1,z);
pd &= bfs(x,y - 1,z);
return pd;
}
int findhole()
{
int cnt = 0;
for (int i = min_x;i <= max_x;i ++)
for (int j = min_y;j <= max_y;j ++)
for (int k = min_z;k <= max_z;k ++)
{
if (grap[i][j][k] == 0 && bfs(i,j,k))
cnt ++;
}
return cnt;
}
int main()
{
int cases,m;
cin >> cases;
while(cases --)
{
cin >> m;
init(m);
cout << findhole() << endl;
}
}