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.![]()
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
#include <bits/stdc++.h>
using namespace std;
int brain[1300][130][65];
int dx[6] = {1,0,-1,0,0,0},dy[6] = {0,-1,0,1,0,0},dz[6] = {0,0,0,0,1,-1};
int m,n,l,t;
int cnt = 0;
void dfs(int x,int y,int z){
brain[x][y][z] = 0;
cnt++;
for(int i = 0;i < 6;i++){
int nx = x + dx[i],ny = y + dy[i],nz = z + dz[i];
if((0 <= nx && nx < m) && (0 <= ny && ny < n) && (0 <= nz && nz < l) && brain[nx][ny][nz]){
dfs(nx,ny,nz);
}
}
}
int main() {
scanf("%d %d %d %d",&m,&n,&l,&t);
for(int z = 0;z < l;z++){
for(int x = 0;x < m;x++){
for(int y = 0;y < n;y++) scanf("%d",&brain[x][y][z]);
}
}
int sum = 0;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
for(int k = 0;k < l;k++){
cnt = 0;
if(brain[i][j][k]) dfs(i,j,k);
sum += cnt < t ? 0 : cnt;
}
}
}
printf("%d\n",sum);
return 0;
} BFS:#include <bits/stdc++.h>
using namespace std;
int brain[1300][130][65];
int dx[6] = {1,-1,0,0,0,0},dy[6] = {0,0,1,-1,0,0},dz[6] = {0,0,0,0,1,-1};
int m,n,l,t;
struct position{
int x,y,z;
position(int x,int y,int z):x(x),y(y),z(z){}
};
int bfs(int x,int y,int z){
int cnt = 0;
queue<position> q;
q.push(position(x,y,z));
brain[x][y][z] = 0;
while(!q.empty()){
position pos = q.front();q.pop();
cnt++;
for(int i = 0;i < 6;i++){
int nx = pos.x + dx[i],ny = pos.y + dy[i],nz = pos.z + dz[i];
if((0 <= nx && nx < m) && (0 <= ny && ny < n) && (0 <= nz && nz < l) && brain[nx][ny][nz]){
brain[nx][ny][nz] = 0;
q.push(position(nx,ny,nz));
}
}
}
return cnt < t ? 0 : cnt;
}
int main() {
scanf("%d %d %d %d",&m,&n,&l,&t);
for(int z = 0;z < l;z++){
for(int x = 0;x < m;x++){
for(int y = 0;y < n;y++) scanf("%d",&brain[x][y][z]);
}
}
int sum = 0;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
for(int k = 0;k < l;k++) if(brain[i][j][k]) sum += bfs(i,j,k);
}
}
printf("%d\n",sum);
return 0;
} #include <iostream>
#include <queue>
#include <cmath>
using namespace std;
struct node{
int x,y,z;
}Node;
int m,n,l,t;
int matrix[1290][130][61];
int inq[1290][130][61]={false};
int X[6]={0,0,0,0,1,-1};
int Y[6]={0,0,1,-1,0,0};
int Z[6]={1,-1,0,0,0,0};
bool judge(int x,int y,int z){
if(x>=m||x<0||y>=n||y<0||z>=l||z<0) return false;
if(matrix[x][y][z]==0||inq[x][y][z]==true) return false;
return true;
}
int BFS(int x,int y,int z){
int tempt=0;
queue<node> q;
Node.x=x;Node.y=y;Node.z=z;
q.push(Node);
inq[x][y][z]=true;
while(!q.empty()){
node top=q.front();
q.pop();
tempt++;
for(int i=0;i<6;i++){
int newx=top.x+X[i];
int newy=top.y+Y[i];
int newz=top.z+Z[i];
if(judge(newx,newy,newz)){
Node.x=newx;Node.y=newy;Node.z=newz;
q.push(Node);
inq[newx][newy][newz]=true;
}
}
}
if(tempt>=t) return tempt;
else return 0;
}
int main(){
cin>>m>>n>>l>>t;
for(int z=0;z<l;z++)
for(int x=0;x<m;x++)
for(int y=0;y<n;y++)
cin>>matrix[x][y][z];
int ans=0;
for(int z=0;z<l;z++)
for(int x=0;x<m;x++)
for(int y=0;y<n;y++)
if(matrix[x][y][z]==1&&inq[x][y][z]==false)
ans+=BFS(x,y,z);
cout<<ans;
return 0;
} #include<iostream>
#include<stdio.h>
#include<queue>
const int maxM = 1300;
const int maxN = 130;
const int maxH = 70;
int square[maxH][maxN][maxM];
bool vis[maxH][maxN][maxM];
using namespace std;
int N, M, L, T;
int ans = 0;
struct Dir{ //the three-dimensianal index of a node
int h, x, y;
};
Dir dir[6] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 0, 0, -1 }, { 0, -1, 0 }, { -1, 0, 0 } }; //tag of direction
bool check(Dir a){
//one of the serious mistakes is that I mixed the N and M in the following line !!!
bool x = (a.h >= 0 && a.h < L && a.x >= 0 && a.x < N && a.y >= 0 && a.y < M);
if ( !x ) return false; //notice that if x==false, square[][][] may out of bounds.
bool y = !vis[a.h][a.x][a.y];
bool z = square[a.h][a.x][a.y];
return ( y && z);
}
int bfs(int h, int x, int y){ //before bfs, make sure it node haven't vesited
queue<Dir>que;
int member = 1; //total piece of a whole chunk
que.push({ h,x,y });
vis[h][x][y] = 1;
while (!que.empty()){
int hh = que.front().h, xx = que.front().x, yy = que.front().y;
que.pop();
for (int i = 0; i < 6; i++){
int nh = hh + dir[i].h, nx = xx + dir[i].x, ny = yy + dir[i].y;
if ( check({ nh, nx, ny }) ){
vis[nh][nx][ny] = 1;
member++;
que.push({ nh, nx, ny });
}
}
}
if (member >= T) ans += member;
return 0;
}
int main(){
scanf("%d%d%d%d", &N, &M, &L, &T);
for (int i = 0; i < L; i++){
for (int j = 0; j < N; j++)
for (int k = 0; k < M; k++)
scanf("%d", &square[i][j][k]);
}
for (int i = 0; i < L; i++){
for (int j = 0; j < N; j++)
for (int k = 0; k < M; k++)
//if(vis[i][j][k]==0) bfs(i, j, k); it is one of the mistake too.
if (check({ i, j, k })) bfs(i,j,k);
}
cout << ans << endl;
return 0;
} 抄 Physicaloser, 题目一直么怎么看懂,又很急躁,就看了一下各位大牛的答案 发现题目关键还是很简单的,不能太急躁了。 现在对题目关键语句进行翻译: 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. 综合思想: 输入 M, N, L and T, (M,N)的矩阵,L是有几个这样的矩阵。 T是阈值,connected的个数大于这个数就算是肿瘤的个数。 #include <iostream> #include <queue> #include <vector> using namespace std; vector<vector<vector<int> > > arr; vector<vector<vector<int> > > marked; int M,N,L,T; int dx[6] = {1,-1,0,0,0,0}; int dy[6] = {0,0,1,-1,0,0}; int dz[6] = {0,0,0,0,1,-1}; int count = 0; int ans = 0; void dfs(int i, int j, int k); int main() { cin >> M >> N >> L >> T; arr.resize(L); marked.resize(L); for(int i=0; i<L; i++) { arr[i].resize(M); marked[i].resize(M); } for(int i=0; i<L; i++) { for(int j=0; j<M; j++) { arr[i][j].resize(N); marked[i][j].resize(N); } } for(int i=0; i<L; i++) { for(int j=0; j<M; j++) { for(int k=0; k<N; k++){ int temp; cin >> temp; arr[i][j][k] = temp; } } } for(int i = 0; i<L; i++) { for(int j=0; j<M; j++) { for(int k=0; k<N; k++) { if(arr[i][j][k] == 1 && !marked[i][j][k]) { count = 0; dfs(i, j, k); if(count >= T) ans += count; } } } } printf("%d\n",ans); return 0; } void dfs(int i, int j, int k) { int t, x, y, z; marked[i][j][k] = 1; if(arr[i][j][k] == 0) return; count ++; for(t=0; t<6; t++) { x = i + dx[t]; y = j + dy[t]; z = k + dz[t]; if (x >= 0 && y >= 0 && z >= 0 && x < L && y < M && z < N && !marked[x][y][z]) dfs(x, y, z); } return; }
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
int G[1286][128][60];
class block
{ public: int x,y,z; block(int xx, int yy, int zz):x(xx),y(yy),z(zz){}
};
int M,N,L,T;
int dx[6] = {1,-1,0,0,0,0};
int dy[6] = {0,0,1,-1,0,0};
int dz[6] = {0,0,0,0,1,-1};
int ans = 0;
bool isValid(int x, int y, int z)
{ return x<M && x>=0 && y<N && y>=0 && z<L && z>=0;
}
void BFS(int x, int y, int z)
{ int result = 0; queue<block> q; q.push(block(x,y,z)); G[x][y][z] = 0; result++; while(!q.empty()) { block t = q.front(); q.pop(); x = t.x; y = t.y; z = t.z; for(int i=0;i<6;i++) { int xx = x + dx[i]; int yy = y + dy[i]; int zz = z + dz[i]; if(isValid(xx, yy, zz) && G[xx][yy][zz]==1) { G[xx][yy][zz] = 0; result++; q.push(block(xx,yy,zz)); } } } if(result >= T) ans += result;
}
int main()
{ 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>>G[i][j][k]; for(int k=0;k<L;k++) for(int i=0;i<M;i++) for(int j=0;j<N;j++) if(G[i][j][k] == 1) BFS(i,j,k); cout<<ans<<endl; return 0;
}
#include <stdio.h>
int a[60][1286][128];
int marked[60][1286][128];
int dx[6] = {-1, 1, 0, 0, 0, 0};
int dy[6] = {0, 0, 1, -1, 0, 0};
int dz[6] = {0, 0, 0, 0, 1, -1};
int count;
void dfs(int i, int j, int k);
int main(void) {
int m, n, l, t, i, j, k;
int volume = 0;
scanf("%d %d %d %d", &m, &n, &l, &t);
for (i = 0; i < l; i++) {
for (j = 0; j < m; j++) {
for (k = 0; k < n; k++) {
scanf("%d", &a[i][j][k]);
}
}
}
for (i = 0; i < l; i++) {
for (j = 0; j < m; j++) {
for (k = 0; k < n; k++) {
if (a[i][j][k] == 1 && !marked[i][j][k]) {
count = 0;
dfs(i, j, k);
if (count >= t)
volume += count;
}
}
}
}
printf("%d\n", volume);
}
void dfs(int i, int j, int k) {
int t, x, y, z;
marked[i][j][k] = 1;
if (a[i][j][k] == 0 )
return;
count++;
for (t = 0; t < 6; t++) {
x = i+dx[t];
y = j+dy[t];
z = k+dz[t];
if (x >= 0 && y >= 0 && z >= 0 && !marked[x][y][z])
dfs(x, y, z);
}
return;
}
int dx[6] = {1,-1,0,0,0,0};
int dy[6] = {0,0,1,-1,0,0};
int dz[6] = {0,0,0,0,1,-1};、
这样在求解连通的方块的时候可以使用一个for循环解决,很久以前我并不知道这种方法,在二维的图中每次都是把同样的代码写四遍,那真是一段黑暗的历史。下面是BFS的代码,使用了STL中的queue,将搜索到的每一个值为1的点入队,下一轮搜索的时候则从队列中再取出一个点进行搜索,简单愉快。
# include <cstdio>
# include <queue>
using std::queue;
int map[1286][128][60];
struct loca
{
int x,y,z;
loca(int _x,int _y,int _z):x(_x),y(_y),z(_z){}
};
int m,n,l,t;
int dx[6] = {1,-1,0,0,0,0};
int dy[6] = {0,0,1,-1,0,0};
int dz[6] = {0,0,0,0,1,-1};
int ans = 0;
int InRange(int x,int y,int z)
{
return x<m&&x>=0&&y<n&&y>=0&&z<l&&z>=0;
}
void bfs(int x,int y,int z)
{
int ret = 0;
queue<loca> que;
que.push(loca(x,y,z));
map[x][y][z] = 0;ret++;
while (!que.empty())
{
loca tp = que.front();que.pop();
x = tp.x;
y = tp.y;
z = tp.z;
for (int i=0;i<6;i++)
{
int nx = x + dx[i];
int ny = y + dy[i];
int nz = z + dz[i];
if (InRange(nx,ny,nz)&&map[nx][ny][nz] == 1)
{
map[nx][ny][nz] = 0;ret++;
que.push(loca(nx,ny,nz));
}
}
}
if (ret>=t)
ans += ret;
}
int main()
{
scanf("%d%d%d%d",&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++)
scanf("%d",&map[i][j][k]);
for (int k=0;k<l;k++)
for (int i=0;i<m;i++)
for (int j=0;j<n;j++)
if (map[i][j][k]==1)
bfs(i,j,k);
printf("%d\n",ans);
return 0;
}
M,N,L,T = map(int,input().split())
slices = []
for _ in range(L):
_slice = []
for _ in range(M):
_slice.append(list(map(int,input().split()))+[0])
_slice.append([0]*(N+1))
slices.append(_slice)
_slice = [[0]*(N+1) for _ in range(M+1)]
slices.append(_slice)
fa = {}
size = {}
for i in range(L):
for j in range(M):
for k in range(N):
if slices[i][j][k]:
fa[(i,j,k)] = (i,j,k)
size[(i,j,k)] = 1
def find(x):#x is tuple
if not fa[x] == x:
fa[x] = find(fa[x])
return fa[x]
def merge(x,y):
root1 = find(x)
root2 = find(y)
if root1 == root2:
return
fa[root1] = root2
size[root2] += size[root1]
for i in range(L):
for j in range(M):
for k in range(N):
if slices[i][j][k]:
if slices[i+1][j][k]:
merge((i+1,j,k),(i,j,k))
if slices[i][j+1][k]:
merge((i,j+1,k),(i,j,k))
if slices[i][j][k+1]:
merge((i,j,k+1),(i,j,k))
ans = 0
for k in fa:
if k == fa[k] and size[k] >= T:
ans += size[k]
print(ans)
我看讨论板都是用bfs做的,这里贴个并查集的暴力做法
#include<bits/stdc++.h>
using namespace std;
const int N = 1e2 + 50;
const int maxn = 1e3 + 500;
const int maxnc = 2e7 + 1000;
int a[66][maxn][N];
int v[maxnc];
int y[66][maxn][N];
//并查集原地秒杀
int fa[maxnc];
void init(int m, int n, int l){
for(int i = 0; i <= m*n*l; i++){
fa[i] = i;
}
}
int find(int x){
if(x == fa[x]){
return x;
}else{
fa[x] = find(fa[x]);
return find(fa[x]);
}
}
void merge(int x, int y){
int fx = find(x);
int fy = find(y);
if(fx != fy){
fa[fx] = fy;
}
}
int cal(int i, int j, int k, int m, int n){
return (i - 1)*m*n + (j - 1)*n + k;
}
int main(){
int m, n, l, t;
cin>>m>>n>>l>>t;
int cnt = 0;
init(m, n, l);
for(int i = 1; i <= l; i++){
for(int j = 1; j <= m; j++){
for(int k = 1; k <= n; k++){
scanf("%d", &a[i][j][k]);
}
}
}
for(int i = 1; i <= l; i++){
for(int j = 1; j <= m; j++){
for(int k = 1; k <= n; k++){
int x = cal(i, j, k, m, n);
if(a[i][j][k]){
if(a[i-1][j][k]) merge(x, cal(i-1,j,k,m,n));
if(a[i][j-1][k]) merge(x, cal(i,j-1,k,m,n));
if(a[i][j+1][k]) merge(x, cal(i, j+1,k,m,n));
if(a[i][j][k-1]) merge(x, cal(i,j,k-1,m,n));
if(a[i][j][k+1]) merge(x, cal(i,j,k+1,m,n));
}
}
}
}
for(int i = 1; i <= l; i++){
for(int j = 1; j <= m; j++){
for(int k = 1; k <= n; k++){
int x = cal(i, j, k, m, n);
if(a[i][j][k]) v[find(x)]++;
}
}
}
int ans = 0;
for(int i = 0; i <= m*n*l; i++){
if(v[i] >= t) ans = ans + v[i];
}
cout<<ans<<endl;
return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct Node {
int x,y,z;
Node() {};
Node(int a,int b,int c):x(a),y(b),z(c) {};
} node;
int m,n,s,t;
int a[1290][130][65];
bool b[1290][130][65];
int X[6]= {0,0,-1,1,0,0};
int Y[6]= {0,0,0,0,-1,1};
int Z[6]= {1,-1,0,0,0,0};
bool Judge(int x,int y,int z) {
if(x>=m||x<0||y>=n||y<0||z>=s||z<0) return 0;
if(a[x][y][z]==0||b[x][y][z]) return 0;
return 1;
}
int BFS(int x,int y,int z) {
queue<Node> q;
q.emplace(Node(x,y,z));
b[x][y][z]=1;
int total=0;
while(!q.empty()) {
Node now=q.front();
q.pop();
total++;
for(int i=0; i<6; i++) {
int newx=now.x+X[i];
int newy=now.y+Y[i];
int newz=now.z+Z[i];
if(Judge(newx,newy,newz)) {
q.emplace(Node(newx,newy,newz));
b[newx][newy][newz]=1;
}
}
}
if(total>=t) {
return total;
} else {
return 0;
}
}
int main() {
scanf("%d %d %d %d",&m,&n,&s,&t);
for(int k=0; k<s; k++) {
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++) {
scanf("%d",&a[i][j][k]);
}
}
}
int ans=0;
for(int k=0; k<s; k++) {
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++) {
if(a[i][j][k]==1&&!b[i][j][k]) {
ans+=BFS(i,j,k);
}
}
}
}
printf("%d\n",ans);
return 0;
} #include <iostream>
#include<vector>
using namespace std;
bool brain[1286][128][60];
bool mark[1286][128][60]{ false };
int M, N, L, T;
//递归DFS
int DFS(int i, int j, int k) {
if (i < 0 || i >= M || j < 0 || j >= N || k < 0 || k >= L || mark[i][j][k] || brain[i][j][k] == 0) return 0;
int _count = 1;
mark[i][j][k] = true;
_count += DFS(i + 1, j, k);
_count += DFS(i - 1, j, k);
_count += DFS(i, j + 1, k);
_count += DFS(i, j - 1, k);
_count += DFS(i, j, k + 1);
_count += DFS(i, j, k - 1);
return _count;
}
//迭代DFS
int _DFS(int i, int j, int k) {
if (mark[i][j][k]) return 0;
int count = 1;
vector<vector<int>> stack;
int offset[][6]{ {1,-1,0,0,0,0},{0,0,1,-1,0,0},{0,0,0,0,1,-1} };
vector<int> start_point;
start_point.push_back(i);
start_point.push_back(j);
start_point.push_back(k);
stack.push_back(start_point);
mark[i][j][k] = true;
while (stack.size()) {
vector<int> point = stack.back();
stack.pop_back();
for (int i = 0; i < 6; i++) {
int x = point[0] + offset[0][i], y = point[1] + offset[1][i], z = point[2] + offset[2][i];
if (brain[x][y][z]&&!mark[x][y][z]) {
mark[x][y][z] = true;
vector<int> next_point;
next_point.push_back(x);
next_point.push_back(y);
next_point.push_back(z);
stack.push_back(next_point);
count++;
}
}
}
return count < T ? 0 : count;
}
int main() {
int count = 0;
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 >> brain[i][j][k]; //递归解法
//for (int k = 0; k < L; k++) for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) if (brain[i][j][k] == true) {
// int v = DFS(i, j, k);
// count += v < T ? 0 : v;
//}
//迭代解法
for (int k = 0; k < L; k++) for (int i = 0; i < M; i++) for (int j = 0; j < N; j++) if (brain[i][j][k] == true)count += _DFS(i, j, k);
cout << count;
} //
#include<iostream>
(720)#include<memory.h>
using namespace std;
int matrix[61][1287][129];
int visit[61][1287][129];
int M, N, L, T;
int dx[6] = { 1,-1,0,0,0,0 };
int dy[6] = { 0,0,1,-1,0,0 };
int dz[6] = { 0,0,0,0,1,-1 };
int dfs(int x, int y, int z) {
int geshu = 0;
if (visit[z][y][x]||matrix[z][y][x]==0) { return 0; }
visit[z][y][x] = 1;
for (int i = 0; i < 6; i++) {
if (z + dz[i] < L && z + dz[i] >= 0 && y + dy[i] >= 0 && y + dy[i] < M && x + dx[i] >= 0 && x + dx[i] < N) {
geshu += dfs(x+dx[i], y + dy[i], z + dz[i]);
}
}
return geshu + 1;
}
int main() {
memset(matrix, 0, sizeof(matrix));
memset(visit, 0, sizeof(visit));
//freopen("C:\\Users\\47\\Desktop\\1.txt","r",stdin);
cin >> M >> N >> L >> T;
for (int i = 0; i < L; i++) {
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
cin >> matrix[i][j][k];
}
}
}
int num = 0;
for (int i = 0; i < L; i++) {
for (int j = 0; j < M; j++) {
for (int k = 0; k < N; k++) {
int t = dfs(k, j, i);
if (t >= T) {
num += t;
}
}
}
}
printf("%d", num);
} #include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
int x,y,z;
}Node;
int n,m,slice,T;
int pix[1290][130][61];//三维01矩阵
bool in[1290][130][61]={false};//记录位置(x,y,z)是否已经入过队
int X[6]={0,0,0,0,1,-1};//增量矩阵
int Y[6]={0,0,1,-1,0,0};
int Z[6]={1,-1,0,0,0,0};
bool judge(int x,int y,int z){
if(x>=n||x<0||y>=m||y<0||z>=slice||z<0) return false;//判断越界
if(pix[x][y][z]==0||in[x][y][z]==true) return false;
return true;
}
int BFS(int x,int y,int z){
int tot=0;//计数当前块中的1的个数
queue<node> Q;//队列
Node.x=x,Node.y=y,Node.z=z;//结点Node的位置为(x,y,z)
Q.push(Node);//结点Node入队
in[x][y][z]=true;
while(!Q.empty()){
node top=Q.front();//取出队首元素
Q.pop();//队首元素出队
tot++;
for(int i=0;i<6;i++){
int newX=top.x+X[i];
int newY=top.y+Y[i];
int newZ=top.z+Z[i];
if(judge(newX,newY,newZ)){
Node.x=newX,Node.y=newY,Node.z=newZ;
Q.push(Node);
in[newX][newY][newZ]=true;
}
}
}
if(tot>=T) return tot;
else return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m>>slice>>T;//矩阵n*m ,共有slice层,T为1个数的下限
for(int z=0;z<slice;z++){//先枚举矩阵编号
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
cin>>pix[x][y][z];
}
}
}
int ans=0;//记录核心区中的1的个数总和
for(int z=0;z<slice;z++){
for(int x=0;x<n;x++){
for(int y=0;y<m;y++){
if(pix[x][y][z]==1&&in[x][y][z]==false){
ans+=BFS(x,y,z);
}
}
}
}
cout<<ans<<endl;
return 0;
}
/*
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*/ #include <iostream>
#include <vector>
#include <cstdio>
#include <cstdlib>
using namespace std;
const int MAX_N = 1286, MAX_M = 128, MAX_L = 60;
const int MAX_LEN = MAX_N * MAX_M * MAX_L;
int MRI[MAX_LEN];
int tot = 0;
int M, N, L, T;
int Union[MAX_LEN];
int count[MAX_LEN];
vector<int> stack(MAX_LEN);
int find(int x){
stack.clear();
while(Union[x] != x){
stack.push_back(x);
x = Union[x];
}
for(int k : stack){
Union[k] = x;
}
return x;
}
void join(int a, int b){
int fa = find(a);
int fb = find(b);
Union[fb] = fa;
if(fa != fb) count[fa] += count[fb];
}
int main(){
// ios::sync_with_stdio(false);
cin >> M >> N >> L >> T;
auto id = [=](int i, int j, int k){
return i * N * L + j * L + k;
};
for(int k = 0; k < L; k++){
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
cin >> MRI[id(i, j, k)];
Union[id(i, j, k)] = id(i, j, k);
if(MRI[id(i, j, k)]) count[id(i, j, k)] = 1;
}
}
}
for(int k = 0; k < L; k++){
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
if(!MRI[id(i, j, k)]) continue;
if(i > 0 && MRI[id(i - 1, j, k)]){
join(id(i, j, k), id(i - 1, j, k));
}
if(i < M - 1 && MRI[id(i + 1, j, k)]){
join(id(i, j, k), id(i + 1, j, k));
}
if(j > 0 && MRI[id(i, j - 1, k)]){
join(id(i, j, k), id(i, j - 1, k));
}
if(j < N - 1 && MRI[id(i, j + 1, k)]){
join(id(i, j, k), id(i, j + 1, k));
}
if(k > 0 && MRI[id(i, j, k - 1)]){
join(id(i, j, k), id(i, j, k - 1));
}
if(k < L - 1 && MRI[id(i, j, k + 1)]){
join(id(i, j, k), id(i, j, k + 1));
}
}
}
}
for(int k = 0; k < L; k++){
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
if(!MRI[id(i, j, k)] || find(id(i, j, k)) != id(i, j, k)) continue;
int c = count[find(id(i, j, k))];
if(c >= T) tot += c;
}
}
}
cout << tot << endl;
// exit(0);
}
这里在PAT官网上DFS会爆栈很多人说过了,还有如果数组开的顺序不一样在PAT上一样会TLE(当然调用顺序也改正确的情况下),牛客的话给的时间比较宽裕,我猜测是跟***数组大小的内存连续缓存有关,如果有知道详细的请指教
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
//这里开数组的顺序是mnl,如果是lmn的顺序在PTA官网上会TLE
int image[1300][200][70],vis[1300][200][70]={0},dir[6][3]={{1,0,0},{-1,0,0},{0,1,0},{0,-1,0},{0,0,1},{0,0,-1}};
int m,n,l,t,ans=0;
struct point
{
int x,y,z;
point(int x,int y,int z)
{
this->x=x;
this->y=y;
this->z=z;
}
};
int bfs(int x,int y,int z)
{
int num=1;
vis[x][y][z]=1;
queue<point> q;
q.push(point(x,y,z));
while(!q.empty())
{
point p=q.front();
q.pop();
for(int i=0;i<6;i++)//每次前后左右上下遍历
{
point next_p=point(p.x+dir[i][0],p.y+dir[i][1],p.z+dir[i][2]);
if(next_p.x<0||next_p.x>=m||next_p.y<0||next_p.y>=n||next_p.z<0||next_p.z>=l||vis[next_p.x][next_p.y][next_p.z]||image[next_p.x][next_p.y][next_p.z]==0)
continue;//边界情况跳出
vis[next_p.x][next_p.y][next_p.z]=1;//标记为已访问并且联通块数量自增
num++;
q.push(next_p);
}
}
return num;
}
int main()
{
scanf("%d %d %d %d",&m,&n,&l,&t);
for(int i=0;i<l;i++)//输入三维图像矩阵
for(int j=0;j<m;j++)
for(int k=0;k<n;k++)
scanf("%d",&image[j][k][i]);
for(int i=0;i<l;i++)
for(int j=0;j<m;j++)
for(int k=0;k<n;k++)
if(!vis[j][k][i]&&image[j][k][i])//如果没被访问过并且该点为1的话开始遍历联通块
{
int num=bfs(j,k,i);
if(num>=t)//联通块数量大于t记录
ans+=num;
}
printf("%d",ans);
return 0;
}
dx,dy,dz = [1,-1,0,0,0,0],[0,0,1,-1,0,0],[0,0,0,0,1,-1] vol,res = [],0 def bfs(z,y,x): global res ret = 0 temp = [] temp.append([z,y,x]) ret+=1 vol[z][y][x]=0 while temp: z,y,x = map(int,temp.pop()) for i in range(6): nz = z+dz[i] ny = y+dy[i] nx = x+dx[i] if (nx<n and nx>=0 and ny<m and ny>=0 and nz<l and nz>=0) and vol[nz][ny][nx]==1: vol[nz][ny][nx] = 0 ret+=1 temp.append([nz,ny,nx]) if ret>=t: res+=ret m,n,l,t = map(int,input().split()) for k in range(l): lst = [] for j in range(m): lst.append(list(map(int,input().split()))) vol.append(lst) for k in range(l): for j in range(m): for i in range(n): if vol[k][j][i]==1: bfs(k,j,i) print(res)参考了大神的思路。贴一个python版本的。注意要节省内存空间。