1. 程式人生 > >湖南大學第十四屆ACM程式設計大賽 B bearBaby loves sleeping

湖南大學第十四屆ACM程式設計大賽 B bearBaby loves sleeping

連結:https://ac.nowcoder.com/acm/contest/338/B
來源:牛客網
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld

題目描述

Sleeping is a favorite of little bearBaby, because the wetness of Changsha in winter is too uncomfortable. One morning, little bearBaby accidentally overslept. The result of being late is very serious. You are the smartest artificial intelligence. Now little bearBaby  asks you to help him figure out the minimum time it takes to reach the teaching building.
The school map is a grid of n*m, each cell is either an open space or a building (cannot pass), and the bedroom of little bearBaby is at (1,1)—— the starting point coordinates.The teaching building is at (x, y)——the target point coordinates, he  can only go up, down, left or right, it takes 1 minute for each step. The input data ensures that the teaching building is reachable.

輸入描述:

The first line has two positive integers n, m , separated by spaces(1 <= n, m <= 100), n for the row, m for the column
Next there are two positive integers x, y, separated by spaces(1 <= x <= n, 1 <= y <= m) indicating the coordinates of the teaching building
Next is a map of n rows and m columns, 0  indicate a open space and 1  indicate a obstacles.
 

輸出描述:

For each test case, output a single line containing an integer giving the minimum time little bearBaby takes to reach the teaching building, in minutes.

示例1

輸入

複製

5 4
4 3
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

輸出

複製

7

說明

For the input example, you could go like this:
(1,1)-->(1,2)-->(2,2)-->(2,3)-->(2,4)-->(3,4)-->(4,4)-->(4,3),so the minimum time is 7.

備註:

First grid in the upper left corner is(1,1)

分析:這是一道經典的走迷宮問題,可使用DFS(深搜)或BFS(廣搜),不過經測試本題用DFS會超時,所以用BFS

同時這道題也是《啊哈演算法》上的經典原題

#include<iostream>
using namespace std;
struct note//定義位置結構體
{
    int x;//記錄到每個點的x座標
    int y;//記錄到每個點的y座標
    int s;//記錄到每個點的步數
};
int main()
{
    struct note que[10005];//定義佇列,10005,由地圖100x100決定。
    int a[101][101]={0},book[101][101]={0};//a用來存放地圖,book用來記錄已經走過的路徑
    int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//定義四個方向,右,下,左,上
    int head,tail;//定義佇列頭,佇列尾
    int i,j,k,n,m,p,q,tx,ty,flag;
    cin>>n>>m;cin>>p>>q;//輸入地圖長和寬,輸入終點座標的x和y
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        cin>>a[i][j];//輸入地形
     
    head=1,tail=1;//初始時先把佇列清空
    que[tail].x=1;//將起點x從1開始
    que[tail].y=1;//將起點y從1開始
    que[tail].s=0;//步數初始化為0
    tail++;//起點正式放入佇列中
    book[1][1]=1;//將起點標記已走過
    flag=0;
    while(head<tail)//佇列不為空則迴圈
    {
        for(k=0;k<=3;k++)//對每個點嘗試四個方向
        {
            tx=que[head].x+next[k][0];
            ty=que[head].y+next[k][1];
            if(tx<1||tx>n||ty<1||ty>m)如果此點越界,則不考慮
            continue;
            if(a[tx][ty]==0&&book[tx][ty]==0)//如果此店無障礙物,且未走過,嘗試放入佇列。
            {
                book[tx][ty]=1;//標記此點已經走過
                que[tail].x=tx;//新的點的x座標放入佇列
                que[tail].y=ty;//新的點的y座標放入佇列
                que[tail].s=que[head].s+1;//走到新的點後步數也要+1
                tail++;
            }
            if(tx==p&&ty==q)//判斷嘗試的新點是否到達終點
            {
                flag=1;//成立則結束
                break;
            }
             
        }
        if(flag==1)
            break;
            head++;//對於該點的四個方向均嘗試過了,這個點就沒有用了,從佇列頭剔除。
    }
    cout<<que[tail-1].s<<endl;//輸出從起點到目標點的最小步數,注意tail指向佇列隊尾的下一個位置
}                                                                 //所以需要-1