时限: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\n",step_num); else printf("No\n"); 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\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 10 2 1 6 8 0 0 0 0 -1 0 0 0 0 0 0 -1 -1 0 0 0 0 -1 0 0 0 0 -1 0 -1 0 0 -1 0 - 0 0 -1 0 -1 0 0 -1 0 - 0 0 0 0 -1 -1 0 -1 0 0 0 0 -1 0 0 0 0 0 0 0 0 -1 0 0 -1 0 -1 -1 0 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 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) 4 5 6 7 -1 11 12 13 14 15 3 -1 -1 8 9 10 11 -1 15 16 2 1 -1 7 -1 11 12 -1 14 -1 3 2 -1 6 -1 12 11 -1 13 -1 4 3 4 5 -1 -1 10 -1 12 13 5 4 -1 6 7 8 9 10 11 12 6 -1 8 7 -1 9 -1 -1 12 13 7 8 9 -1 11 10 11 -1 17 -1 -1 9 10 -1 12 11 12 -1 16 -1 11 10 11 12 13 12 13 14 15 -1 */