1. 程式人生 > >[Sicily 1114 Food Cubes] 廣度優先搜尋

[Sicily 1114 Food Cubes] 廣度優先搜尋

(1)問題描述:

對於三維空間的某一個座標而言,如果它的上、下、左、右、前後都有food cubes的話,這個座標就可以稱之為一個hole。

現在給出所有food cubes的座標,需要求出有多少個holes。

座標x、y、z的範圍都是1-100

(2)基本思路:

對於不是food cubes的座標,進行廣度優先搜尋。

假設搜尋完整個空間需要count次,則hole的個數是(count - 1)。

需要注意的是邊界條件的判斷(想象一個2乘2的立方體,左上角和右下角是food cubes,那麼它的hole數應該是0,就可以知道為什麼邊界條件這樣設定了)。

bool valid(int x, int y, int z)
{
	return (x >= 0 && x <= 101 && y >= 0 && y <= 101 && z >= 0 && z <= 101);
}

(3)程式碼實現:

#include<iostream>
#include<queue>
using namespace std;
#define MAX 102
int cube[MAX][MAX][MAX];
int dx[6] = {0, 0, 1, -1, 0, 0};
int dy[6] = {0, 0, 0, 0, 1, -1};
int dz[6] = {1, -1, 0, 0, 0, 0};
struct Node
{
	int x, y, z;
	Node(int _x, int _y, int _z)
	{
		x = _x;
		y = _y;
		z = _z;
	}
};
bool valid(int x, int y, int z)
{
	return (x >= 0 && x <= 101 && y >= 0 && y <= 101 && z >= 0 && z <= 101);
}
void bfs(int sx, int sy, int sz)
{
	int tx;
	int ty;
	int tz;
	queue<Node> q;
	q.push(Node(sx, sy, sz));
	cube[sx][sy][sz] = 1;
	while(!q.empty())
	{
		Node top = q.front();
		for(int i = 0; i < 6; i++)
		{
			tx = top.x + dx[i];
			ty = top.y + dy[i];
			tz = top.z + dz[i];
			if(valid(tx, ty, tz) && cube[tx][ty][tz] == 0)
			{
				q.push(Node(tx, ty, tz));
				cube[tx][ty][tz] = 1;
			}
		}	
		q.pop();
	}
}
int main()
{
	int t;//number of test cases
	cin >> t;
	while(t--)
	{
		int m;//the number of food cubes
		int x, y, z;
		cin >> m;
		for(int i = 0; i < MAX; i++)
		{
			for(int j = 0; j < MAX; j++)
			{
				for(int l = 0; l < MAX; l++)
					cube[i][j][l] = 0;
			}
		}
		for(int i = 0; i < m; i++)
		{
			cin >> x >> y >> z;
			cube[x][y][z] = 1;
		}
		int count = 0;
		for(int i = 0; i < MAX; i++)
		{
			for(int j = 0; j < MAX; j++)
			{
				for(int l = 0; l < MAX; l++)
				{
					if(cube[i][j][l] == 0)
					{
						bfs(i, j, l);
						count++;
					}
				}
			}
		}
		cout << count - 1 << endl;
	}
	return 0;	
}