toj 2815 Searching Problem

本文介绍了一个寻宝迷宫问题的算法实现,玩家需要在迷宫中找到宝藏并计算最少所需子弹数来应对守护宝藏的狗。通过广度优先搜索(BFS)算法解决了这一问题,并确保了从起点到宝藏路径的最短距离。
2815.   Searching Problem
Time Limit: 1.0 Seconds    Memory Limit: 65536K
Total Runs: 421    Accepted Runs: 177



It is said that the predecessors had hidden a lot of expensive treasures just before the death of their city hundreds of years ago. People's searching for it has never stopped. The only problem is that they can't tell the exact position of the treasure. What's more, there exists great dangerousness in searching. So although the treasure has been their place for countries, it's still safe.

You are one of the people who want to make a fortune. However, you're a very lucky man. You happen to get a secret map, and you know the map can lead you to the treasure directly.

The map is a maze. There are five symbols on the map. They are 'S', 'D', '$', '1' and '0'. 'S' is the point you enter into the maze. '$' stand for the treasure in the maze. '0' and 'D' are the points you can walk along, while '1' is walls that you can't go through. You shall start at the 'S' point, and pick up the treasure in the maze along the '0' and 'D' points, then come out along the same way.

It seems easy, and you'll become a wealthy man. But there is still a problem you have to solve. On every point marked as a 'D' there is a dog to protect the treasure. It's absurd that the dogs can live for countries without food! Just forget about it. So you decide to bring a gun with you. But how many bullets it will take? It's up to you to calculate here. Assume that you're a good shooter, and need only one bullet to shoot one dog.

Input

The first line of each test case is two integer R and C (1 ≤ R, C ≤ 50). R is the row number of the maze, and C is the column number of the maze. The following R lines will contain C characters for each. The R * C characters includes exactly one 'S' and one '$', the remains are '1', '0' and 'D'. It guarantees that the 'S' point is always on the edge of the maze.

Two zeros indicate the end of the input.

Output

For each case, just print a line with the number K, which is the least number of bullets you need.

Sample Input

4 5
00$00
00100
D00D0
S0001
4 5
00$00
01100
D00D0
S0001
4 5
DDDDD
DD$DD
D0D0D
SDD0D
0 0

Sample Output

0
1
2

Problem Setter: Venice



Source: TJU Programming Contest 2007
Submit   List    Runs   Forum   Statistics

#include  < iostream >
#include 
< queue >
#define  MAX 54
using   namespace  std;
int  mark[MAX][MAX],a[ 4 ][ 2 ] = {{ - 1 , 0 },{ 1 , 0 },{ 0 , 1 },{ 0 , - 1 }};
char  map[MAX][MAX];
typedef 
struct  node
{
    
int  x;
    
int  y;
    
int  step;
}Point;
queue
< Point > Q;
Point start,p,temp;
int  r,c,MM;
void  Init()
{
    
int  i,j,k;
    
for (i = 0 ;i < r;i ++ )
        
for (j = 0 ;j < c;j ++ )
        {
            cin
>> map[i][j];
            
if (map[i][j] == ' S ' )
            {
                start.x
= i;
                start.y
= j;
                start.step
= 0 ;
            }
            mark[i][j]
=- 1 ;
        }
}
bool  Bound( int  x, int  y)
{
    
if (x >= 0 && y >= 0 && x < r && y < c)
        
return   true ;
    
else
        
return   false ;
}
void  BFS()
{
    
int  k,tx,ty;
    
while ( ! Q.empty())
        Q.pop();
    Q.push(start);
    mark[start.x][start.y]
= 0 ;
    MM
=- 1 ;
    
while ( ! Q.empty())
    {
        p
= Q.front();
        Q.pop();
        
if (map[p.x][p.y] == ' $ ' )
        {
            
if (p.step < MM || MM ==- 1 )
            {
                MM
= p.step;
            }
        }
        
for (k = 0 ;k < 4 ;k ++ )
        {
            tx
= p.x + a[k][ 0 ];
            ty
= p.y + a[k][ 1 ];
            
if ( ! Bound(tx,ty) || map[tx][ty] == ' 1 ' )
                
continue ;
            
if (map[tx][ty] == ' 0 ' || map[tx][ty] == ' $ ' )
            {
                
if (mark[tx][ty] ==- 1 || p.step < mark[tx][ty])
                {
                    temp.x
= tx;
                    temp.y
= ty;
                    temp.step
= p.step;
                    mark[tx][ty]
= p.step;
                    Q.push(temp);
                }
                
continue ;
            }
            
if (map[tx][ty] == ' D ' )
            {
                temp.step
= p.step + 1 ;
                
if (mark[tx][ty] ==- 1 || temp.step < mark[tx][ty])
                {
                    temp.x
= tx;
                    temp.y
= ty;
                    
// temp.step=p.step;
                    mark[tx][ty] = temp.step;
                    Q.push(temp);
                }
                
continue ;
            }
        }
    }
    printf(
" %d\n " ,MM);
}
int  main()
{
    
while (scanf( " %d%d " , & r, & c) != EOF)
    {
        
if (r == 0 && c == 0 )
            
break ;
        Init();
        BFS();
    }
    
return   0 ;
}

转载于:https://www.cnblogs.com/forever4444/archive/2009/05/14/1456965.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值