原题链接:http://www.patest.cn/contests/pat-a-practise/1091
本题的前4个case容易过,最后两个case有些难度。如果单纯递归,递归层次会很高从而导致栈溢出,若手动模拟栈实现,又会超出内存限额,于是考虑每次只遍历可连接的节点的个数不超过临界值t。如果节点块连接值达到t,则对这些有效节点进行标记,否则看它们有没有有效的邻节点,若有的话也认为其为有效节点,否则认为其无效。可AC代码如下:
#include <iostream>
#include <vector>
using namespace std;
int m,n,l,t;
char matrix[61][1287][129];
bool visited[61][1287][129];
bool isvalid[61][1287][129];
bool getvalid(int x, int y, int z)
//得到当前节点有效性记录
{
if(x<0 || x>=l ||
y<0 || y>=m ||
z<0 || z>=n)
{
return false;
}
return isvalid[x][y][z];
}
bool getsidevalid(int x, int y, int z)
//得到当前节点邻节点有效性逻辑结果
{
if(x<0 || x>=l ||
y<0 || y>=m ||
z<0 || z>=n)
{
return false;
}
return getvalid(x-1,y,z) || getvalid(x+1,y,z) || getvalid(x,y-1,z) ||
getvalid(x,y+1,z) || getvalid(x,y,z-1) || getvalid(x,y,z+1);
}
int getval(int x, int y, int z)
//若当前节点是否为未访问的‘1’节点,返回记录值1
{
if(x<0 || x>=l ||
y<0 || y>=m ||
z<0 || z>=n ||
visited[x][y][z] ||
matrix[x][y][z] == '0')
{
return 0;
}
visited[x][y][z] = true;
return 1;
}
int calvolume(int x, int y, int z)
//以当前节点为起始节点,遍历与其相连的节点和它构成的块,块的大小不超过t
{
if(x<0 || x>=l ||
y<0 || y>=m ||
z<0 || z>=n ||
visited[x][y][z] ||
matrix[x][y][z] == '0' ||
getval(x,y,z) != 1)
{
return 0;
}
if(getsidevalid(x,y,z))
{
isvalid[x][y][z] = true;
return 1;
}
int volume = 1, ptr = 0;
bool forbidadd = false;
vector<int> xvec,yvec,zvec;//记录块中节点的数组
xvec.push_back(x);//添加起始节点
yvec.push_back(y);
zvec.push_back(z);
while(xvec.size()>0)
{
bool allvalid = false;
if(!forbidadd)
{
int xt,yt,zt;
for(int i = 0; i < 3; i++)
for(int j = -1; j <= 1; j+=2)
//添加ptr所指vector中记录节点邻节点
{
xt = xvec[ptr];
yt = yvec[ptr];
zt = zvec[ptr];
if(i == 0)xt += j;
if(i == 1)yt += j;
if(i == 2)zt += j;
if(getval(xt,yt,zt) == 1)
{
xvec.push_back(xt);
yvec.push_back(yt);
zvec.push_back(zt);
volume++;
if(getsidevalid(xt,yt,zt))
//若其邻节点有有效邻居,则认为当前节点块有效
{
allvalid = true;
}
}
}
}
ptr++;
if(allvalid || xvec.size() >= t)
//若已判断定当前块有效,或节点块节点数量已达t
{
forbidadd = true;
for(int i = 0; i < xvec.size(); i++)
{
isvalid[xvec[i]][yvec[i]][zvec[i]] = true;
}
break;
}
if(ptr == xvec.size())
//若节点块已经遍历完全
{
break;
}
}
xvec.clear();
yvec.clear();
zvec.clear();
return volume;
}
int main()
{
int num = 0;
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];
}
for(int i = 0; i < l; i++)
for(int j = 0; j < m; j++)
for(int k = 0; k < n; k++)
{
int count = 0;
if(matrix[i][j][k]=='1' && !visited[i][j][k])
{
count = calvolume(i,j,k);
if(count >= t || isvalid[i][j][k])
num += count;
}
}
cout<<num<<endl;
}原文:http://blog.csdn.net/u011669093/article/details/41606701