zoukankan      html  css  js  c++  java
  • 走迷宫(回溯)求路径长度/最短路径表

    时限:1000ms 内存限制:10000K  总时限:3000ms 描述:

    判断是否能从迷宫的入口到达出口

    输入: 先输入两个整数表示迷宫的行数m和列数n,再输入口和出口的坐标,最后分m行输入迷宫,其中1表示墙,0表示空格每个数字之间都有空格。

    输出: 若能到达终点,输出从起点到终点的(最短?)路径长度,

             走不通时输出“No”

    输入样例:(行列坐标从0开始)

    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 1

    输出样例:

    28

    #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
    ",step_num);
        else
            printf("No
    ");    
        return 0;
    }

    变:要求输出从起点到终点的最短路径步数及对应的最短路径

        (路障不再用“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
    ",step_num);
            printPath(MinPATH);//打印路径
            printMat(Arr);//打印迷宫---有方格在路径中的位置
        }
        else
            printf("No
    "); 
    
        //cin>>step_num;//VS2010上调试用
        return 0;
    }
    void printPath(stack<Postion> MinPATH)
    {
        while (!MinPATH.empty())
        {
            printf("%2d---(%d,%d)
    ",Arr[MinPATH.top().X][MinPATH.top().Y]-1, 
                                     MinPATH.top().X, MinPATH.top().Y);//输出从终点到起点的路径
            MinPATH.pop();
        }
        printf(" 0---(%d,%d)
    ",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("
    ");
        }
    }
    /*
    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
    */
  • 相关阅读:
    Maven关于web.xml中Servlet和Servlet映射的问题
    intellij idea的Maven项目运行报程序包找不到的错误
    修改Maven项目默认JDK版本
    刷题15. 3Sum
    刷题11. Container With Most Water
    刷题10. Regular Expression Matching
    刷题5. Longest Palindromic Substring
    刷题4. Median of Two Sorted Arrays
    刷题3. Longest Substring Without Repeating Characters
    刷题2. Add Two Numbers
  • 原文地址:https://www.cnblogs.com/IThaitian/p/3583148.html
Copyright © 2011-2022 走看看