题213.2022寒假天梯赛训练-7-13 肿瘤诊断 (30 分)
一、题目
二、题解
开始看这题的时候就没懂啥意思,想好久才知道我们可以把L个M*N的切片叠起来变成一个MNL的三维立体(切片+像素连通“上下左右前后”暗示),之后在三维立体中去bfs找连通集(连通体暗示),只有连通集的点数>=T,才加入到总体积。依上述操作,代码如下:
#include <bits/stdc++.h>
using namespace std;
//定义每次试探的规则,左右前后上下
const int dx[6]={0,0,1,-1,0,0};
const int dy[6]={-1,1,0,0,0,0};
const int dz[6]={0,0,0,0,1,-1};
int M,N,L,T;
struct Point//开一个结构体去存点,方便操作
{
int x,y,z;
Point(int x,int y,int z)//构造方法便于造点
{
this->x=x;
this->y=y;
this->z=z;
}
};
int bfs(vector<vector<vector<int>>> &G,vector<vector<vector<int>>> &vis,Point p0)
{
int num=0;
queue<Point> q;
q.push(p0);
vis[p0.x][p0.y][p0.z]=1;//标记访问
while(!q.empty())
{
Point temp=q.front();
num++;
q.pop();
for(int i=0;i<6;i++)//探寻找周围为1且没有被访问过的像素点
{
if(vis[temp.x+dx[i]][temp.y+dy[i]][temp.z+dz[i]]!=1&&G[temp.x+dx[i]][temp.y+dy[i]][temp.z+dz[i]]==1)
{
q.push(Point(temp.x+dx[i],temp.y+dy[i],temp.z+dz[i]));
vis[temp.x+dx[i]][temp.y+dy[i]][temp.z+dz[i]]=1;
}
}
}
if(num>=T)//体积大于等于T才能算
{
return num;
}
else
{
return 0;
}
}
int main()
{
cin>>M>>N>>L>>T;
vector<vector<vector<int>>> G(M+2,vector<vector<int>>(N+2,vector<int>(L+2,0)));//定义每一维长度都是原长度+2的三维数组去存图,初始化为0
vector<vector<vector<int>>> vis(M+2,vector<vector<int>>(N+2,vector<int>(L+2,0)));//vis记录该点是否被访问过
for(int k=1;k<=L;k++)
{
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
scanf("%d",&G[i][j][k]);//输入图
}
}
}
int total=0;
for(int k=1;k<=L;k++)
{
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
if(vis[i][j][k]!=1&&G[i][j][k]==1)//只有为该点为异常像素并且先前没有被访问过才去bfs访问
{
total+=bfs(G,vis,Point(i,j,k));//每次bfs都会得到体积加入到总体积中
}
}
}
}
cout<<total;
}