(刷算法学英语)PAT甲级--Acute Stroke(三维空间的bfs)

Posted C_YCBX Py_YYDS

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(刷算法学英语)PAT甲级--Acute Stroke(三维空间的bfs)相关的知识,希望对你有一定的参考价值。


我的个人小站

题目


OJ平台

题目翻译

题目描述

原文
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.
翻译
识别急性脑卒中(急性脑卒中)的一个重要因素是卒中核心的体积。 鉴于在每个 MRI 切片中识别出核心区域的图像分析结果,您的工作是计算中风核心的体积。

输入描述

原文
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).
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.
翻译
每个输入文件包含一个测试用例。 对于每种情况,第一行包含 4 个正整数:M、N、L 和 T,其中 M 和 N 是每个切片的大小(即切片的像素在 M × N 矩阵中,最大分辨率为 1286 * 128); L (<=60) 是大脑切片的数量; T 是整数阈值(即,如果连接的核心的体积小于 T,则该核心不得计算在内)。
然后给出L个切片。 每个切片由一个由 0 和 1 组成的 M × N 矩阵表示,其中 1 表示笔画的一个像素,0 表示正常。 由于切片的厚度是常数,因此我们只需计算 1 的数量即可获得体积。 但是,一个大脑中可能有几个独立的核心区域,只有体积不小于T的才被计算在内。 两个像素是“连接的”,因此如果它们共享一个公共边则属于同一区域,如图 1 所示,其中所有 6 个红色像素都连接到蓝色像素。

如图中所表示的这一个方块代表0/1,这一层一层的代表一层一层的切片,如图中的六个相邻方向,则代表两个像素是连接的。

输出描述

原文
For each case, output in a line the total volume of the stroke core.
翻译
对每一个测试用例,输出一行表示核心的总体积(实际就是计算相邻1的数量)。

解题分析

读完题目,我们发现,它所输入的很多个切片,其实是叠在一起的,所以应该使用三维数组存储,然后通过bfs或者dfs搜索即可。(超级简单的遍历。。。)

解题代码

基本参量

int M, N, L, T;
int v[1286][128][60];//用于存储输入数据
int res = 0;//得到答案
int cnt = 0;//记录每次dfs得到的连通块数量

//根据图中的六个方向构造:横轴的上下左右,以及纵轴的上下方向
int dx[] = {1, -1, 0, 0, 0, 0};
int dy[] = {0, 0, -1, 1, 0, 0};
int dz[] = {0, 0, 0, 0, 1, -1};

Input函数

void Input() {
    ios::sync_with_stdio(false);
    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 >> v[i][j][k];
            }
        }
    }
}

check函数和dfs函数

inline bool check(int x, int y, int z) {
    return x >= 0 && x < M && y >= 0 && y < N && z >= 0 && z < L;
}
void dfs(int x, int y, int z) {
    v[x][y][z] = 0;
    cnt++;
    for (int i = 0; i < 6; i++) {
        int t_x = x + dx[i], t_y = y + dy[i], t_z = z + dz[i];
        if (check(t_x, t_y, t_z) && v[t_x][t_y][t_z])
            dfs(t_x, t_y, t_z);
    }
}

print函数

void print() {
    for (int i = 0; i < M; i++)
    for (int j = 0; j < N; j++)
    for (int k = 0; k < L; k++)
        if (v[i][j][k]) {
            dfs(i, j, k);
            if (cnt >= T)
                res += cnt;
            cnt = 0;
        }
    cout << res;
}

整合代码得到答案

应该非常好懂,而且效率也还行

#include<bits/stdc++.h>
using namespace std;
int M, N, L, T;
int v[1286][128][60];
int res = 0;
int cnt = 0;
//根据图中的六个方向构造:横轴的上下左右,以及纵轴的上下方向
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 Input() {
    ios::sync_with_stdio(false);
    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 >> v[i][j][k];
            }
        }
    }
}
inline bool check(int x, int y, int z) {
    return x >= 0 && x < M && y >= 0 && y < N && z >= 0 && z < L;
}
void dfs(int x, int y, int z) {
    v[x][y][z] = 0;
    cnt++;
    for (int i = 0; i < 6; i++) {
        int t_x = x + dx[i], t_y = y + dy[i], t_z = z + dz[i];
        if (check(t_x, t_y, t_z) && v[t_x][t_y][t_z])
            dfs(t_x, t_y, t_z);
    }
}
void print() {
    for (int i = 0; i < M; i++)
    for (int j = 0; j < N; j++)
    for (int k = 0; k < L; k++)
        if (v[i][j][k]) {
            dfs(i, j, k);
            if (cnt >= T)
                res += cnt;
            cnt = 0;
        }
    cout << res;
}
int main() {
    Input();
    print();
    return 0;
}

以上是关于(刷算法学英语)PAT甲级--Acute Stroke(三维空间的bfs)的主要内容,如果未能解决你的问题,请参考以下文章

PAT甲级——A1091 Acute Stroke30

PAT甲级——1091 Acute Stroke (广度优先搜索BFS)

(学英语学算法)PAT甲级--All Roads Lead to Rome

PAT甲级刷题实录——1014

pat甲级考试+pat1051+1056

PAT甲级刷题实录——1011