走迷宮(回溯)求路徑長度/最短路徑表

時限:1000ms 內存限制:10000K  總時限:3000ms 描述:ios

判斷是否能從迷宮的入口到達出口函數

輸入: 先輸入兩個整數表示迷宮的行數m和列數n,再輸入口和出口的座標,最後分m行輸入迷宮,其中1表示牆,0表示空格每一個數字之間都有空格。佈局

輸出: 若能到達終點,輸出從起點到終點的(最短?)路徑長度,spa

         走不通時輸出「No」調試

輸入樣例:(行列座標從0開始)code

12 12
1 8 
10 7
1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 1 0 1 1 1
1 0 1 0 1 1 0 0 0 0 0 1
1 0 1 0 1 1 0 1 1 1 0 1
1 0 1 0 0 0 0 0 1 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 
1 0 0 0 1 0 1 0 0 0 0 1
1 0 1 1 1 0 0 0 1 1 1 1
1 0 0 0 0 0 1 0 0 0 0 1
1 1 1 0 1 1 1 1 0 1 0 1
1 1 1 1 1 1 1 0 0 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1blog

輸出樣例:內存

28ci

#include<stdio.h>
int Arr[30][30];//最大迷宮爲30*30
int Rownum=0,Colnum=0;//行列數
int Beginrow,Begincol,Endrow,Endcol;//終點座標
int state=0;//迷宮走通與否狀態
int canplace(int row,int col)//判斷當前點可否走通
{
    if(row>=0 &&col>=0 &&row<Rownum &&col<Colnum &&Arr[row][col]==0)//爲越界且可走通
        return 1;
    return 0;
}
void search(int row,int col)
{
    if(row==Endrow && col==Endcol)//是目標終點    
    {    state=1;  return ;   }
    
    int r,c,num;
        num=Arr[row][col];
        //Arr[row][col]=1;//對可走通的點進行標記
        r=row-1; c=col; //
    if(canplace(r,c))  { Arr[r][c]=num+1; search(r,c); }
    r=row; c=col+1;//
    if(canplace(r,c))  { Arr[r][c]=num+1; search(r,c); }
    r=row+1;  c=col;//
    if(canplace(r,c))  { Arr[r][c]=num+1; search(r,c); }
    r=row;    c=col-1;//
    if(canplace(r,c))  { Arr[r][c]=num+1; search(r,c); }
}
int main()
{ 
    int i,j;
    scanf("%d%d",&Rownum,&Colnum);//輸入迷宮行列數  
    scanf("%d%d%d%d",&Beginrow,&Begincol,&Endrow,&Endcol);//起始點,終點座標
    for(i=0;i<Rownum;i++)
        for(j=0;j<Colnum;j++)
           scanf("%d",&Arr[i][j]);       //一行一行的輸入迷宮佈局
    
    Arr[Beginrow][Begincol]=1;
    search(Beginrow,Begincol);
    //一個迷宮搜索路徑後的最終狀態,起始點接通與否
    int step_num=step_num=Arr[Endrow][Endcol]-1;
    if(state==1)
        printf("%d\n",step_num);
    else
        printf("No\n");    
    return 0;
}

 

變:要求輸出從起點到終點的最短路徑步數及對應的最短路徑io

    (路障再也不用「1」表示而用」-1「表示)

#include <stack>
#include <iostream>
using namespace std;
int Arr[30][30];//最大迷宮爲30*30
int Rownum=0,Colnum=0;//行列數
int Beginrow,Begincol,Endrow,Endcol;//終點座標
int state=0;//迷宮走通與否狀態
struct Postion
{
    int X, Y;
    Postion(){}//構造函數
    Postion(int X, int Y): X(X), Y(Y){}
};
void printPath(stack<Postion> MinPATH);
void printMat(int Arr[30][30]);

//////////////////////////////////////////////////////////////////////////////////////////
bool canplace(int prePosValue,int row,int col)//判斷當前點可否走通
{
    if(row>=0 &&col>=0 &&row<Rownum &&col<Colnum &&Arr[row][col]!=-1)//未越界且不是牆(-1)
        if(Arr[row][col]==0) return true;
        else  return (prePosValue + 1)<Arr[row][col];// 更近的路徑,也算可走通
    return 0;
}
stack<Postion>MinPATH;// 記錄最短路徑    
void search(stack<Postion>&path,int row,int col)
{
    if(row==Endrow &&col==Endcol)//是目標終點  
    {
        if(path.size()<MinPATH.size() || MinPATH.empty())//更短的路徑
        {
            state=1;
            MinPATH = path;
        }
        return;
    }
       
    int r,c,num;
    num=Arr[row][col];
    //Arr[row][col]=1;//對可走通的點進行標記
    r=row-1; c=col; //
    {
        if(canplace(num,r,c))  
        { 
            Arr[r][c]=num+1; 
            path.push(Postion(r,c));//[r,c]進棧
            search(path,r,c); //深度優先搜索
            path.pop();//[r,c]出棧,退回到棧頂爲[row,col]
        }
    }    
    r=row; c=col+1;//
    {
        if(canplace(num,r,c))  
        { 
            Arr[r][c]=num+1; 
            path.push(Postion(r,c));//進棧
            search(path,r,c); //深度優先搜索
            path.pop();//出棧 
        }
    }  
    r=row+1;  c=col;//
    {
        if(canplace(num,r,c))  
        { 
            Arr[r][c]=num+1; 
            path.push(Postion(r,c));//進棧
            search(path,r,c); //深度優先搜索
            path.pop();//出棧
        }
    }    
    r=row;  c=col-1;//
    {
        if(canplace(num,r,c))   
        { 
            Arr[r][c]=num+1; 
            path.push(Postion(r,c));//進棧
            search(path,r,c); //深度優先搜索
            path.pop();//出棧 
        }
    }
}
//////////////////////////////////////////////////////////////////////////////////////


int main()
{ 
    int i,j;
    scanf("%d%d",&Rownum,&Colnum);//輸入迷宮行列數  
    scanf("%d%d%d%d",&Beginrow,&Begincol,&Endrow,&Endcol);//起始點,終點座標
    for(i=0;i<Rownum;i++)
        for(j=0;j<Colnum;j++)
           scanf("%d",&Arr[i][j]);       //一行一行的輸入迷宮佈局
    
    Arr[Beginrow][Begincol]=1;
    search(stack<Postion>(),Beginrow,Begincol);
    //一個迷宮搜索路徑後的最終狀態,起始點接通與否
    int step_num=Arr[Endrow][Endcol]-1;
    if(state==1)
    {
        printf("最少步數:%d\n",step_num);
        printPath(MinPATH);//打印路徑
        printMat(Arr);//打印迷宮---有方格在路徑中的位置
    }
    else
        printf("No\n"); 

    //cin>>step_num;//VS2010上調試用
    return 0;
}
void printPath(stack<Postion> MinPATH)
{
    while (!MinPATH.empty())
    {
        printf("%2d---(%d,%d)\n",Arr[MinPATH.top().X][MinPATH.top().Y]-1, 
                                 MinPATH.top().X, MinPATH.top().Y);//輸出從終點到起點的路徑
        MinPATH.pop();
    }
    printf(" 0---(%d,%d)\n",Beginrow, Begincol);//起始點的座標
}
void printMat(int Arr[30][30])
{
    for (int i = 0; i < 10 ; i++)
    {
        for (int j = 0; j < 10 ; j++)
            printf("%2d ", Arr[i][j]);
        printf("\n");
    }
}
/*
10
1
8
 0  0  0  -1 0  0  0   0  0
 -1 -1 0  0  0  0  -1  0  0
 0  -1 0  -1 0  0  -1  0  -
 0  -1 0  -1 0  0  -1  0  -
 0  0  0  -1 -1 0  -1  0  0
 0  -1 0  0  0  0  0   0  0
 -1 0  0  -1 0  -1 -1  0  0
 0  0  -1 0  0  0  -1  0  -
-1 0  0  -1 0  0  0  -1  0  -
 0  0  0  0  0  0  0   0  -
最少步數:11
11---(6,8)
10---(5,8)
 9---(5,7)
 8---(5,6)
 7---(5,5)
 6---(5,4)
 5---(5,3)
 4---(4,3)
 3---(4,2)
 2---(4,1)
 1---(3,1)
 0---(2,1)
 5  6  7 -1 11 12 13 14 15
-1 -1  8  9 10 11 -1 15 16
 1 -1  7 -1 11 12 -1 14 -1
 2 -1  6 -1 12 11 -1 13 -1
 3  4  5 -1 -1 10 -1 12 13
 4 -1  6  7  8  9 10 11 12
-1  8  7 -1  9 -1 -1 12 13
 8  9 -1 11 10 11 -1 17 -1
-1  9 10 -1 12 11 12 -1 16 -1
10 11 12 13 12 13 14 15 -1
*/
相關文章
相關標籤/搜索