先访问完当前顶点的所有邻接点,然后再访问下一层的所有节点
例如
他的顺序应为
一层一层的走,先是1号点,然后是与1号点直接相邻的所有节点,再然后是直接与第2层相邻的点,以此类推。
代码和详解如下
#include<stdio.h>
struct ma {
int x; // 横坐标
int y; // 纵坐标
int s; // 步数
};
int a[405][405]; // 用于输入,容纳矩阵
int book[405][405] = { 0 }; // 用于检查是否走过
int main() {
struct ma queue[160000];
int head; // 队首
int tail; // 队尾
int n, m, p, q;
int tx, ty;
scanf("%d %d %d %d", &n, &m,&p,&q);
for(int g=0;g<=n;g++)
{
for(int l=0;l<=m;l++)
{
a[g][l]=-1;
}
}
head = 1;
tail = 1;
queue[tail].x = p;
queue[tail].y = q;
queue[tail].s = 0; // 将起始位置的步数设为0
tail++;
book[p][q] = 1;
a[p][q]=0;
int next[8][2] = { {-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1},{-2,-1},{-2,1} }; // 马的八个行走方向
while (head < tail) // 队列的循环
{
for (int i = 0; i < 8; i++) {
tx = queue[head].x + next[i][0];
ty = queue[head].y + next[i][1];
if (tx > n || tx < 1 || ty > m || ty < 1) // 下一步可以行走的范围
{
continue;
}
if (book[tx][ty] == 0) // 重复经历的不走
{
queue[tail].s = queue[head].s + 1; // 将下一步节点的步数设置为当前节点的步数加1
a[tx][ty] = queue[tail].s; // 将步数存入相对应的格子中
queue[tail].x = tx; // 将新节点插入数据中
queue[tail].y = ty;
tail++;
book[tx][ty] = 1;
}
}
head++;
}
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= m; k++) {
printf("%-5d", a[j][k]); // 输出结果
}
printf("\n");
}
return 0;
}
手结冰了只能这样了(这些图)
代码如下
#include<stdio.h>
struct tu{
int x;//横坐标
int y;//纵坐标
};
int main()
{
struct tu f[1000];//队列
int a[35][35];//存储输入的数组
int book[35][35]={0};//用于标记
int n;
scanf("%d",&n);
int head;
int tail;
head=1;
tail=1;
f[tail].x =0;
f[tail].y =0;
tail++;
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=n+1;j++)
{
a[i][j]=0;
}
}//将原本的数组进行拓展,这可以使得外层可能间断的0连续便于搜索
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}//输入数组
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//上下左右四个方向
book[0][0]=1;
int tx;//横坐标的下一步
int ty;//纵坐标的下一步
while(head<tail)
{
for(int k=0;k<4;k++)
{
tx=f[head].x +next[k][0];
ty=f[head].y +next[k][1];
if(tx<0||tx>n+1||ty<0||ty>n+1)
{
continue;
}
if(book[tx][ty]==0&&a[tx][ty]!=1)//条件是该点坐标不等于1且不重复
{book[tx][ty]=1;
f[tail].x =tx;
f[tail].y =ty;
a[tx][ty]=3;//这个也比较重要,这个起着将搜索到的0标记之后再判断如果是3就输出0;
tail++;
//将新数据弄进队列
}
}
head++;
}
for(int k=1;k<=n;k++)
{
for(int j=1;j<=n;j++)
{
if(a[k][j]==3){printf("0 ");
}
if(a[k][j]==1)//是1就输出1
{
printf("1 ");
}
if(a[k][j]==0)//如果是0就输出2,外面的0经过搜索全部已经被标记成3了
{
printf("2 ");
}
}printf("\n");
}
}
还有一个
、
之前第一层都是一个初始点现在有多个把这些初始的点(绿色的那些点)全部送进队列里一起作为第一层开始搜索,从这些绿色的点开始蔓延,蔓延过的上标记,这样矩阵中的每一个点到绿点的距离都是最近的。
#include <stdio.h>
struct w {
int x;
int y;
int s;
};
int book[501][501];
int a[501][501];
int main() {
struct w f[250005];
int n, m, p, q;
int head, tail;
head = 1;
tail = 1;
scanf("%d %d %d %d", &n, &m, &p, &q);
for (int i = 1; i <= p; i++) {
int o, r;
scanf("%d %d", &o, &r);
f[tail].x = o;
f[tail].y = r;
f[tail].s = 0;
a[o][r] = 0;
book[o][r] = 1;
tail++;
}//把这些初始点全部送进队列后面都是收悉的配方
int next[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
while (head < tail) {
for (int j = 0; j < 4; j++) {
int tx = f[head].x + next[j][0];
int ty = f[head].y + next[j][1];
if (tx < 1 || tx > n || ty < 1 || ty > m) {
continue;
}
if (book[tx][ty] == 0) {
book[tx][ty] = 1;
f[tail].x = tx;
f[tail].y = ty;
f[tail].s = f[head].s + 1;
a[tx][ty] = f[tail].s;
tail++;
}
}
head++;
}
int e[2501];
int l=0;
for (int s = 1; s <= q; s++) {
int g, h;
scanf("%d %d", &g, &h);
e[l]=a[g][h];
l++;
}
for(int z=0;z<l;z++)
{
printf("%d\n",e[z]);
}
return 0;
}
明天计划:
写题单