3:魔鬼之城
源程序名 pils.???(pas, c, cpp) 可执行文件名 pils.exe 输入文件名 pils.in 输出文件名 pils.out |
【问题描述】
在一个被分割为N*M个正方形房间的矩形魔鬼之城中,一个探险者必须遵循下列规则才能跳跃行动。他必须从(1, 1)进入,从(N, M)走出;在每一房间的墙壁上都写了一个魔法数字,是1~13之内的自然数;探险者可以想像出8个方向中的任何一个(水平或垂直或对角线方向),随后他就可以作一次空间跳跃穿过这一方向上的连续的X个房间,其中X是他原来所在房间的魔法数字。但如果在这一方向上的房间数小于X,则他不作任何跳跃,而必须想像另一个方向。同时,探险者不能作连续两次相同方向的跳跃。
| 1 | 2 | 3 | 4 | 5 |
1 | 3 | 3 | 6 | 7 | 11 |
2 | 3 | 2 | 1 | 1 | 3 |
3 | 3 | 2 | 2 | 1 | 1 |
4 | 2 | 1 | 2 | 2 | 1 |
例如在上图的5*4的魔鬼之城中,如果探险者现在所在的位置是(3, 3),那么通过依次空间跳跃他可以到达下列房间中的一个:(1, 1),(3, 1),(1, 3),(5, 1),或(5, 3)。另外,如果他要用两次跳跃从(5, 4)到达(3, 2),则他不能首先跳到(4, 3)(因为这样他第二次跳跃的方向将和第一次相同,而这是不允许的)。所以他必须先跳跃到(2, 1)。
请你写一个程序,对给定的地图,算出探险者至少需要跳跃多少步才能离开魔鬼之城。
【输入】
一行给出N,M(都不超过100);
下来有M行,每行为N个自然数,表示对应房间中的魔法数字。
【输出】
出最小步数,如果探险者无法离开魔鬼之城,请输出“NEVER”。
【样例】
pils.in pils.out
5 4 4
3 3 6 7 11
3 2 1 1 3
3 2 2 1 1
2 1 2 2 1
很简单的广搜,有点类似于拆点的思想
#include <cstdio>
#include <string>
const long dx[] = {-1,-1,-1,0,1,1,1,0};
const long dy[] = {-1,0,1,1,1,0,-1,-1};
bool used[110][110][20];
struct node
{
long i,j,de,t;
};
node que[1000000];
long map[110][110];
const long quemod = 1000000;
long getint()
{
long rs=0;char tmp;bool sgn=1;
do tmp = getchar();
while (!isdigit(tmp)&&tmp-'-');
if (tmp=='-'){sgn=0;tmp=getchar();}
do rs=(rs<<3)+(rs<<1)+tmp-'0';
while (isdigit(tmp=getchar()));
return sgn?rs:-rs;
}
int main()
{
freopen("pils.in","r",stdin);
freopen("pils.out","w",stdout);
long m = getint();
long n = getint();
for (long i=1;i<n+1;i++)
for (long j=1;j<m+1;j++)
map[i][j] = getint();
long l = 0;
long r = 0;
r ++;
que[r].i = 1;
que[r].j = 1;
que[r].t = 0;
que[r].de = -1;
node u;
node v;
long i,j,de,t;
while (l != r)
{
l ++;
if (l >= quemod)
l = 1;
u = que[l];
i = u.i;
j = u.j;
de = u.de;
t = u.t;
if (i == n && j == m)
{
printf("%ld",t);
return 0;
}
for (long d=0;d<8;d++)
{
if (d == de)
continue;
long di = dx[d] * map[i][j];
long dj = dy[d] * map[i][j];
long ni = i + di;
long nj = j + dj;
if (ni>n || ni<1 || nj>m || nj<1)
continue;
if (!used[ni][nj][d])
{
used[ni][nj][d] = true;
r ++;
if (r >= quemod)
r = 1;
que[r].i = ni;
que[r].j = nj;
que[r].de = d;
que[r].t = t+1;
}
}
}
printf("NEVER");
return 0;
}