搜索作业一共两道题,上一道深搜那这一道当然宽搜了。。。哈哈
感觉这种棋盘类型的题我第一步想的都是先把四周边缘先封上,然后从起点开始,每搜到一个点,它的步数都是原来点的步数加1,所以步数还是好解决的。。然后马有八种不同的走法,我用的是4个元素的数组加双层循环来遍历八种走法,然后搜到点就入队,完事这个点能走的都搜完了就出队,等到队空了循环也该结束了,没搜到的自然就是走不到的了。然后最后输出的时候我看洛谷上的题解都是有各式各样的对齐方法是吧,当时也没想这么多,没考虑这个对齐不过也还是AC了。。最让我头疼的就是N的范围啊,当时队列开得太小了一直90分都不知道错哪儿了,de了半天把N改大就过了
#include <iostream>
using namespace std;
const int N=160010;
bool judge[410][410];
int t[410][410];
int qx[N],qy[N],hh=0,tt=0;//队列的初始化
int main()
{
int n,m,x,y;
cin>>n>>m>>x>>y;
for(int i=0;i<=n+3;i++)
{
for(int j=0;j<=m+3;j++)
{
t[i][j]=-1,judge[i][j]=1;//t用来存步数 judge用来判断这个点是否使用过
}
}
t[x+1][y+1]=0;
judge[x+1][y+1]=0;//起点的初始化
for(int j=0;j<=m+3;j++)
{//接下来四组循环做的是同一个事情,把四周先给封死不要走外面去
judge[0][j]=0;
judge[1][j]=0;
}
for(int j=0;j<=m+3;j++)
{
judge[n+2][j]=0;
judge[n+3][j]=0;
}
for(int i=2;i<=n+1;i++)
{
judge[i][0]=0;
judge[i][1]=0;
}
for(int i=2;i<=n+1;i++)
{
judge[i][m+2]=0;
judge[i][m+3]=0;
}
qx[tt]=x+1,qy[tt++]=y+1;//起点入队
int a[4]={-2,-1,1,2};//用一个数组加两层for循环来表示八种不同的走法
while(1)
{
int i=0,j=0;
for(i=0;i<=3;i++)
{
for(j=0;j<=3;j++)
{
if(a[i]!=a[j]&&a[i]!=-a[j]&&judge[qx[hh]+a[i]][qy[hh]+a[j]])
{
judge[qx[hh]+a[i]][qy[hh]+a[j]]=0;
qx[tt]=qx[hh]+a[i];
qy[tt++]=qy[hh]+a[j];//搜到的新的点入队
t[qx[hh]+a[i]][qy[hh]+a[j]]=t[qx[hh]][qy[hh]]+1;
}//新点的步数就是它原来的点的步数+1
}
}
hh++; //这个点能走到的所有点位都搜完了,就该出队了
if(hh==tt)break;//队列空了表示搜索结束
}
for(int i=2;i<=n+1;i++)
{
for(int j=2;j<=m+1;j++)
{
if(t[i][j]==-1)cout<<-1<<" ";
else cout<<t[i][j]<<" ";
}//这里我当时不知道那些对齐的方法,于是来了个笨办法哈哈,也成功AC了
cout<<endl;
}
return 0;
}