您的位置:首页 > 其它

1091.Acute Stroke

2015-01-28 19:23 197 查看
【题意】
给出一个三维空间的 01 矩阵,算出所有超出阈值的相连的1的数目

【思路】
看到题目描述马上想到了并查集,不过我之前的题目都没用并查集写过,于是有点手生,好在最后还是成功AC,正好练练手了

【注意点】
在归并集合时6个方向只要找坐标减小的3个方向即可,多找了没必要而且会超时

#include <iostream>
#include <vector>
#include <map>
using namespace std;

vector<vector<vector<bool>>> valid;
vector<vector<vector<int>>> pre;
int m,n,l,t;

void init(){
for(int i=0; i<l; i++){
for(int j=0; j<m; j++){
for(int k=0; k<n; k++){
pre[i][j][k] = i*m*n+j*n+k;
}
}
}
}

int root(int a, int b, int c){
if(a*m*n+b*n+c!=pre[a][b][c]){
int x,y,z;
z = pre[a][b][c]/(m*n);
x = (pre[a][b][c]%(m*n))/n;
y = (pre[a][b][c])%n;
pre[a][b][c] = root(z,x,y);
}
return pre[a][b][c];
}

void merge(int a1, int b1, int c1, int a2, int b2, int c2){
int x[2],y[2],z[2],roots[2];

roots[0] = root(a1,b1,c1);
roots[1] = root(a2,b2,c2);
for(int i=0; i<2; i++){
z[i] = roots[i]/(m*n);
x[i] = (roots[i]%(m*n))/n;
y[i] = roots[i]%n;
}

if(roots[0]!=roots[1]){
pre[z[0]][x[0]][y[0]] = pre[z[1]][x[1]][y[1]];
}
}

int main(int argc, char const *argv[])
{
cin >> m >> n >> l >> t;
pre.resize(l,vector<vector<int>>(m,vector<int>(n)));
valid.assign(l,vector<vector<bool>>(m,vector<bool>(n,0)));

for(int i=0; i<l; i++){
for(int j=0; j<m; j++){
for(int k=0; k<n; k++){
cin >> pre[i][j][k];
if(pre[i][j][k]){
valid[i][j][k] = 1;
}
}
}
}

init();

for(int i=0; i<l; i++){
for(int j=0; j<m; j++){
for(int k=0; k<n; k++){
if(valid[i][j][k]){
if(i>=1 && valid[i-1][j][k]){
merge(i,j,k,i-1,j,k);
}
if(j>=1 && valid[i][j-1][k]){
merge(i,j,k,i,j-1,k);
}
if(k>=1 && valid[i][j][k-1]){
merge(i,j,k,i,j,k-1);
}
}
}
}
}

map<int,int> volumes;
for(int i=0; i<l; i++){
for(int j=0; j<m; j++){
for(int k=0; k<n; k++){
if(valid[i][j][k]){
volumes[root(i,j,k)]++;
}
}
}
}

int cnt = 0;
for(map<int,int>::iterator it=volumes.begin(); it!=volumes.end(); it++){
if(it->second>=t){
cnt += it->second;
}
}

cout << cnt;

system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: