1.注意边界(0或1的差别)
2.输入m*n矩阵时 因为从1开始 所以必须c[i]+1以确保能读到第一列数
3.注意是从head位置开始向四个方向搜索,所以不是kx=x+xx[i],而是kx=a[head].x+xx[i]
4.运用队列 从上到下 从左到右寻找细胞 令找到的细胞入队并标记为'0'
【代码】
#include <bits/stdc++.h>
using namespace std;
char c[1005][1005];
struct s{
int x,y;
}a[1000005];
int n,m;
int head,tail,ans;//定义首尾指针
int xx[4]={-1,0,1,0};
int yy[4]={0,1,0,-1};//偏置数组
void bfs(int x,int y){
int kx,ky;
head=1,tail=2;//赋初值
a[head].x=x;
a[head].y=y;
while(head<tail){
for(int i=0;i<4;i++){
kx=a[head].x+xx[i];
ky=a[head].y+yy[i];//从head位置开始向四个方向搜索
if(kx<1||kx>n||ky<1||ky>m||c[kx][ky]=='0') continue;//合法判断
c[kx][ky]='0';//把已经搜索过的不为0的点标记为0
a[tail].x=kx;
a[tail].y=ky;//搜索到tail的位置
tail++;//需要开下一个tail
}
head++; //继续从下一个head开始搜索
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
scanf("%s",c[i]+1);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(c[i][j]!='0'){
c[i][j]='0';
bfs(i,j);//从i,j开始广搜
ans++;//放入队列 计数
}
}
}
cout<<ans;
return 0;
}
【分析】
1.选择方法 可以直接从所给位置走到(1,1) 进行两次广搜输出步数 也可以直接从(1,1)开始走 经过所给位置并输出步数
2.注意偏置数组的设置 本题中马既可以走“日” 也可以走“田” 因此有十二个方向
【代码】
#include <bits/stdc++.h>
using namespace std;
int s[105][105],b[105][105];//s为棋盘,b用来记录步数
struct S{
int x,y;
}a[10005];
int xx[12]={-2,-2,-1,1,2,2,2,2,1,-1,-2,-2};
int yy[12]={1,2,2,2,2,1,-1,-2,-2,-2,-2,-1};
int ax,ay,bx,by;
void bfs(int x,int y){
int head,tail;
head=0,tail=1;
a[head].x=x;
a[head].y=y;
b[x][y]=0;//还没走时(head位置)步数初值为0
s[x][y]=1;//标记初始位置为1表明走过
while(head<tail){
int kx,ky;
for(int i=0;i<12;i++){//日+田 马共有十二个方向
kx=a[head].x+xx[i];
ky=a[head].y+yy[i];
if(kx<0||kx>100||ky<0||ky>100||s[kx][ky]==1) continue;//判断合法
a[tail].x=kx;
a[tail].y=ky;
s[kx][ky]=1;//标记走过的点为1
b[kx][ky]=b[a[head].x][a[head].y]+1;//b数组计数(原来的值加一)
if(kx==1 && ky==1){//当到达点(1,1)时
cout<<b[kx][ky]<<endl;//输出步数
head=tail;
break;//两步跳出循环
}
tail++;
}
head++;//拓展下一个点
}
}
int main(){
cin>>ax>>ay>>bx>>by;
if(ax==1&&ay==1) cout<<0<<endl;
else bfs(ax,ay);
memset(s,0,sizeof(s));//一定要清零 避免留下每次标记造成混乱
if(bx==1&&by==1) cout<<0<<endl;//如果初始位置在(1,1)就不需要走
else bfs(bx,by);
return 0;
}
【分析】
1.注意不同字符的含义
2.有多组测试数据 需要清零 记得写“当在一行中读入的是两个零时,表示输入结束”
【代码】
#include <bits/stdc++.h>
using namespace std;
char c[25][25];//迷阵
struct s{
int x,y;
}a[500];
int b[25][25],l[25][25];//b数组计数,l数组标记走过的点
int xx[4]={-1,0,1,0};
int yy[4]={0,1,0,-1};
int m,n;
void bfs(int x,int y){
int head=0,tail=1;
a[head].x=x;
a[head].y=y;
l[x][y]=1;
int flag=0;//假设不能找到仙药
while(head<tail){
int kx,ky;
for(int i=0;i<4;i++){
kx=a[head].x+xx[i];
ky=a[head].y+yy[i];
if(kx<1||kx>m||ky<1||ky>n||c[kx][ky]=='#'||l[kx][ky]==1) continue;//这里多了一个有怪物('#')的情况
a[tail].x=kx;
a[tail].y=ky;
l[kx][ky]=1;//标记走过的点
b[kx][ky]=b[a[head].x][a[head].y]+1;//计数耶
if(c[kx][ky]=='*'){//如果找到了仙药
head=tail;
cout<<b[kx][ky]<<endl;
flag=1;//标记flag为1
}
tail++;
}
head++;//拓展下一个
}
if(flag==0) cout<<-1<<endl;//如果flag仍为0 即不能找到仙药 输出-1
}
int main(){
while(cin>>m>>n){
if(m==0 && n==0) break; //读入数据 遇到两个0时停止
memset(l,0,sizeof(l));
memset(b,0,sizeof(b));//记得清零 两个都要T_T
int x,y;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>c[i][j];//输入矩阵
if(c[i][j]=='@'){//李逍遥的位置
x=i;
y=j;//设为起点
}
}
}
bfs(x,y);//从起点开始广搜
}
return 0;
}