> Description
如下图12×12方格图,找出一条自入口(2,9)到出口(11,8)的最短路径。
> Input
> Output
> Sample Input
12 //迷宫大小
2 9 11 8 //起点和终点
1 1 1 1 1 1 1 1 1 1 1 1 //邻接矩阵,0表示通,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 0 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
> Sample Output
(2,9)->(3,9)->(3,8)->(3,7)->(4,7)->(5,7)->(5,6)->(5,5)->(5,4)->(6,4)->(7,4)->(7,3)->(7,2)->(8,2)->(9,2)->(9,3)->(9,4)->(9,5)->(9,6)->(8,6)->(8,7)->(8,8)->(9,8)->(9,9)->(10,9)->(11,9)->(11,8)
27
> 解题思路
这一题用广搜解。
a[maxn][maxn]表示矩形方阵;f[maxn*maxn]表示列队;
s[maxn*maxn][3],1表示当前点的横坐标,2表示纵坐标,记录状态。
如果当前的位置可以走的话就tail加1,把当前位置的父结点加入队列;当现在的head(父结点)已经没有子结点的话,就把head加1,把上一个已经没有子结点的父结点退出队列。
只要是走过的路线都要把它赋值为1(障碍),防止有重复的路线,而且先到某一个路线的一定是最快最优的。
然后就像这样>>
> 代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int d1[5]={0,-1,0,0,1},d2[5]={0,0,-1,1,0};
//这里是表示当前位置的四条路线
const int maxn=1001;
int a[maxn][maxn],f[maxn*maxn],s[maxn*maxn][3];
int n,a1,b1,a2,b2,len;
bool aka(int q1,int q2)
{
if(a[q1][q2]==1) return false;
return true;
}//判断是否越界
void output(int x)
{
if(x==1) return;
len++;
output(f[x]);
printf("->(%d,%d)",s[x][1],s[x][2]);
}
void lil()
{
int h=0,t=1;
f[t]=0;//第一个的父结点一定是0
s[1][1]=a1; s[1][2]=b1;
a[a1][b1]=1;//把起点看做是走过了,设为障碍
do
{
h++;
for(int k=1;k<=4;k++)
{
if(aka(s[h][1]+d1[k],s[h][2]+d2[k]))
{
t++;
f[t]=h;//把这一个路线加入队列
s[t][1]=s[h][1]+d1[k];
s[t][2]=s[h][2]+d2[k];
a[s[t][1]][s[t][2]]=1;
//走过的设为障碍1
}
if(s[t][1]==a2&&s[t][2]==b2)
//当已经到达终点就输出返回
{
len=1;
printf("(%d,%d)",a1,b1);
output(t);
printf("\n%d",len);
return;
}
}
}while(h<=t);
}
int main()
{
memset(a,1,sizeof(a));
//不管是障碍还是界限外,都把它看为是障碍1
scanf("%d%d%d%d%d",&n,&a1,&b1,&a2,&b2);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
lil();
return 0;
}