1091-Acute Stroke (30)

1004

題目

題目描述

One important factor to identify acute stroke (急性腦卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions are identified in each MRI slice, your job is to calculate the volume of the stroke core.

輸入描述:

Then L slices are given. Each slice is represented by an M by N matrix of 0's and 1's, where 1 represents a pixel of stroke, and 0 means normal. Since the thickness of a slice is a constant, we only have to count the number of 1's to obtain the volume. However, there might be several separated core regions in a brain, and only those with their volumes no less than T are counted. Two pixels are "connected" and hence belong to the same region if they share a common side, as shown by Figure 1 where all the 6 red pixels are connected to the blue one.Each input file contains one test case. For each case, the first line contains 4 positive integers: M, N, L and T, where M and N are the sizes of each slice (i.e. pixels of a slice are in an M by N matrix, and the maximum resolution is 1286 by 128); L (<=60) is the number of slices of a brain; and T is the integer threshold (i.e. if the volume of a connected core is less than T, then that core must not be counted).


Figure 1

輸出描述:

For each case, output in a line the total volume of the stroke core.

輸入例子:

3 4 5 2
1 1 1 1
1 1 1 1
1 1 1 1
0 0 1 1
0 0 1 1
0 0 1 1
1 0 1 1
0 1 0 0
0 0 0 0
1 0 1 1
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 1
1 0 0 0

輸出例子:

26

算法分析

圖:BFS、連通塊

STL:隊列的使用<queue>

三維圖問題,求出1個數大於闕值的連通塊數目。

連通塊問題容易讓人想到DFS,但本題需要在6個方向上遍歷,遞歸的層數極多,對堆棧的要求高,容易造成棧溢出。故本題選用BFS進行遍歷。

代碼

#include <iostream>
#include <queue>
using namespace std;

const int MAXX = 1286;
const int MAXY = 128;
const int MAXZ = 60;
const int di_x[6] = { -1,1,0,0,0,0 };	//沿X軸的移動方向,下同
const int di_y[6] = { 0,0,-1,1,0,0 };
const int di_z[6] = { 0,0,0,0,-1,1 };
int graph[MAXX][MAXY][MAXZ] = { 0 };
int M, N, L, T;		//x,y,z,threshold
int count1 = 0;	//符合要求的像素點1的個數
typedef struct Node {
	Node(int a, int b, int c) : x(a), y(b), z(c) {}
	int x, y, z;
}Node;

void BFS(int x, int y, int z) {
	queue<Node> q;
	q.push(Node(x, y, z));		//進隊
	int cur_count = 1;
	graph[x][y][z] = 0;		//將該像素點標記爲已遍歷

	while (!q.empty()) {
		Node temp = q.front();		//隊列頭元素
		q.pop();
		graph[temp.x][temp.y][temp.z] = 0;	//標記當前點

		for (int i = 0; i < 6; i++) {	//處理6個方向
			int newx = temp.x + di_x[i];
			int newy = temp.y + di_y[i];
			int newz = temp.z + di_z[i];

			if (newx < 0 || newx >= M || newy < 0 || newy >= N || newz < 0 || newz >= L)
				continue;
			if (0 == graph[newx][newy][newz])
				continue;
			//是連通點
			cur_count++;
			graph[newx][newy][newz] = 0;
			q.push(Node(newx, newy, newz));		//BFS,每訪問完一個點(無論是否有效)都把它加入到隊列尾部
		}
	}
	if (cur_count >= T)
		count1 += cur_count;

	return;
}

int main(void) {
	cin >> M >> N >> L >> T;
	for (int k = 0; k < L; k++)
		for (int i = 0; i < M; i++)
			for (int j = 0; j < N; j++)		//注意三維空間的遍歷順序!!!
				cin >> graph[i][j][k];

	//不是強連通圖,故在DFS/BFS時需要外加循環遍歷
	for (int k = 0; k < L; k++)
		for (int i = 0; i < M; i++)
			for (int j = 0; j < N; j++)
				if (1 == graph[i][j][k])
					BFS(i, j, k);

	cout << count1 << endl;
	system("pause");
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章