解释这个代码每部分的作用
时间: 2023-07-02 22:16:45 浏览: 103
好的,下面我来逐步解释一下这个代码的每部分作用。
首先我们看到的是头文件和结构体定义:
```c
#include <stdio.h>
typedef struct note{
int x;
int f;
int s;
}NOTE;
```
这里只包含了一个头文件和一个结构体定义。`NOTE` 结构体用于保存每个节点的状态,包括点的值 `x`,前一个节点的下标 `f` 和到起点的步数 `s`。
接下来是主函数:
```c
int p[100001];
int book[100001];
int main() {
int s,k,flag=0,head,tail,tx,i;
int next[3]={-1,1,2};
scanf("%d%d",&s,&k);
head=1;tail=1;
p[head].x=s;
p[head].f=0;
p[head].s=0;
tail++;
book[s]=1;
while(head<tail)
{
for(i=0;i<3;i++)
{
if(i!=2)
tx=p[head].x+next[i];
else
tx=p[head].x*next[i];
if(tx<0||tx>100000)
continue;
if(book[tx]==0)
{
book[tx]=1;
p[tail].x=tx;
p[tail].f=head;
p[tail].s=p[head].s+1;
tail++;
}
if(tx==k)
{
flag=1;
break;
}
}
if(flag==1) break;
head++;
}
printf("%d\n",p[tail-1].s);
return 0;
}
```
这个主函数主要分为以下几个部分:
1. 定义变量和数组:
```c
int s,k,flag=0,head,tail,tx,i;
int next[3]={-1,1,2};
int p[100001];
int book[100001];
```
`s` 和 `k` 分别代表起点和终点, `flag` 用于记录是否已经找到了终点,`head` 和 `tail` 分别代表队头和队尾的下标,`tx` 代表拓展节点后得到的新节点的值, `i` 代表循环计数器。`next` 数组保存了每次拓展节点时需要加上的偏移量,即向左、向右和乘以2。
`p` 数组用于保存每个节点的状态,包括点的值 `x`,前一个节点的下标 `f` 和到起点的步数 `s`。`book` 数组用于记录每个节点是否已经被扩展过。
2. 输入起点和终点:
```c
scanf("%d%d",&s,&k);
```
3. 初始化队列:
```c
head=1;
tail=1;
p[head].x=s;
p[head].f=0;
p[head].s=0;
tail++;
book[s]=1;
```
队列初始化时,先将起点加入队列,并将其状态(包括点的值 `x`,前一个节点的下标 `f` 和到起点的步数 `s`)保存到 `p[1]` 中。同时,将起点标记为已经被扩展过。
4. 开始 BFS:
```c
while(head<tail)
{
for(i=0;i<3;i++)
{
if(i!=2)
tx=p[head].x+next[i];
else
tx=p[head].x*next[i];
if(tx<0||tx>100000)
continue;
if(book[tx]==0)
{
book[tx]=1;
p[tail].x=tx;
p[tail].f=head;
p[tail].s=p[head].s+1;
tail++;
}
if(tx==k)
{
flag=1;
break;
}
}
if(flag==1) break;
head++;
}
```
在这里使用了一个 `while` 循环,只要队列不为空(即 `head` 小于 `tail`),就进行 BFS。每次取出队头,然后向左、向右和乘以2,拓展新的节点,并将其加入队列中。同时,将新节点标记为已经被扩展过。如果拓展得到的新节点的值等于终点,则记录下来并跳出循环。
5. 输出结果:
```c
printf("%d\n",p[tail-1].s);
```
输出到达终点的最短步数,即 `p[tail-1].s`。
这就是这个代码的每部分作用了,希望能对你有所帮助。
阅读全文