MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
题目地址:
http://acm.hdu.edu.cn/showproblem.php?pid=1253
题目描述:
胜利大逃亡
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4785 Accepted Submission(s): 1454
魔王住在一个城堡里,城堡是一个A*B*C的立方体,可以被表示成A个B*C的矩阵,刚开始Ignatius被关在(0,0,0)的位置,离开城堡的门在(A-1,B-1,C-1)的位置,现在知道魔王将在T分钟后回到城堡,Ignatius每分钟能从一个坐标走到相邻的六个坐标中的其中一个.现在给你城堡的地图,请你计算出Ignatius能否在魔王回来前离开城堡(只要走到出口就算离开城堡,如果走到出口的时候魔王刚好回来也算逃亡成功),如果可以请输出需要多少分钟才能离开,如果不能则输出-1.
特别注意:本题的测试数据非常大,请使用scanf输入,我不能保证使用cin能不超时.在本OJ上请使用Visual C++提交.
题目分析:
这题和 二维矩阵的不同点就是有6个方向, 前后左右上下. 然后一直BFS就可以了,不需要剪枝都能过...........
代码如下:
/*
MiYu原创, 转帖请注明 : 转载自 ______________白白の屋
http://www.cnblog.com/MiYu
Author By : MiYu
Test : 1
Program : HDU1253
*/
#include
#include
using namespace std;
int TLE[56][56][56];
const int d[6][3] = { { 0,0,1 },{ 0,0,-1 },{ 0,-1,0 },{ 0,1,0 },{ 1,0,0 },{ -1,0,0 } };
int A, B, C, T, m;
typedef struct pos{
pos(){ x=y=z=n=0; }
void setPos ( int a,int b,int c, int count ){ x=a;y=b;z=c;n=count; }
bool isEnd () { if ( x==1&&y==1&&z==1 )return true;return false; }
int x,y,z;
int n;
}pos;
pos t,p;
#define CMP(A,B) (A.n < B.n)
typedef class Heap {
public:
pos h[70000 * 2];
int n, p, c;
Heap() {
n = 0;
}
void inline push(pos e) {
for (p = ++n; p > 1 && CMP(e,h[p>>1]); h[p] = h[p>>1], p >>= 1)
;
h[p] = e;
}
int inline pop(pos &e) {
if (!n)
return 0;
for (e = h[p = 1], c = 2; c < n
&& CMP(h[c += (CMP(h[c + 1],h[c]) && c < n - 1)], h[n]);
h[p] = h[c], p = c, c <<= 1)
;
h[p] = h[n--];
return 1;
}
}Heap;
Heap WA;
int RE ()
{
if ( A+B+C-2 > T || TLE[A][B][C] == 0 )
return -1;
t.setPos ( A,B,C,0 );
TLE[A][B][C] = 0;
WA.push ( t );
while ( WA.pop(t) ){
if ( t.x+t.y+t.z-2 > T-t.n )
continue;
if ( t.isEnd() )
return t.n;
for ( int i = 0; i != 6; ++ i ){
int x = t.x+d[i][0], y=t.y+d[i][1], z=t.z+d[i][2];
if ( TLE[ x ][ y ][ z ] != 0 ){
TLE[ x ][ y ][ z ] = 0;
p.setPos ( x, y, z, t.n+1 );
if ( p.isEnd() && p.n <= T )
return p.n;
if ( p.n <= T )
WA.push ( p );
}
}
}
return -1;
}
inline bool scan_d(int &num)
{
char in;bool IsN=false;
in=getchar();
if(in==EOF) return false;
while(in!='-'&&(in<'0'||in>'9')) in=getchar();
if(in=='-'){ IsN=true;num=0;}
else num=in-'0';
while(in=getchar(),in>='0'&&in<='9'){
num*=10,num+=in-'0';
}
if(IsN) num=-num;
return true;
}
int main ()
{
int K;
scan_d(K);
while ( K -- ){
while ( WA.pop(p) ) ;
memset ( TLE, 0 , sizeof ( TLE ) );
scan_d(A); scan_d(B); scan_d(C); scan_d(T);
for ( int i = 1; i <= A; ++ i ){
for ( int j = 1; j <= B; ++ j ){
for ( int k = 1; k <= C; ++ k ){
scan_d(m);
TLE[i][j][k] = m == 1 ? 0 : 1;
}
}
}
TLE[1][1][1] = 1;
cout << RE () << endl;
}
//system( "pause" );
return 0;
}