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版本的。注意要节省内存空间。