想了想,主要是有个题感觉怪怪的,今天还是弄两个其他的题吧
//# 【深基16.例3】二叉树深度
//## 题目描述
//有一个 n(n \le 10^6) 个结点的二叉树。给出每个结点的两个子结点编号(均不超过 n),建立一棵二叉树(根节点的编号为 $1$),如果是叶子结点,则输入 `0 0`。
//
//建好这棵二叉树之后,请求出它的深度。二叉树的深度是指从根节点到叶子结点时,最多经过了几层。
//
//## 输入格式
//
//第一行一个整数 n,表示结点数。
//
//之后 n 行,第 i 行两个整数 l、r,分别表示结点 i 的左右子结点编号。若 l=0 则表示无左子结点,r=0 同理。
//
//## 输出格式
//
//一个整数,表示最大结点深度。
//
//## 样例 #1
//
//### 样例输入 #1
//7
//2 7
//3 6
//4 5
//0 0
//0 0
//0 0
//0 0
//输出
//4
//方法1
大体思路:简单的dps,我们主要是利用递归来实现搜索,我们输入的时候需要将数组开大一点,
可以像第一种方法一样直接去搜索不加条件,也可以第二和第三一样加上跳出条件(这样时间短一点)
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}tree[1000005];
int ans=-1;
void dfs(int pos,int deep)
{
ans=max(ans,deep);
if(tree[pos].l)
dfs(tree[pos].l,deep+1);
if(tree[pos].r)
dfs(tree[pos].r,deep+1);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>tree[i].l>>tree[i].r;
dfs(1,1);
cout<<ans;
}
//方法二
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}tree[1000005];
int ans=-1;
void dfs(int pos,int deep)
{
if(pos==0)
return ;
dfs(tree[pos].l,deep+1);
dfs(tree[pos].r,deep+1);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>tree[i].l>>tree[i].r;
dfs(1,1);
cout<<ans;
}
//方法三
#include<bits/stdc++.h>
using namespace std;
struct node{
int l,r;
}tree[1000005];
int ans=-1;
void dfs(int pos,int deep)
{
if(tree[pos].l==0&&tree[pos].r==0){
ans=max(ans,deep);
return ;
}
dfs(tree[pos].l,deep+1);
dfs(tree[pos].r,deep+1);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>tree[i].l>>tree[i].r;
dfs(1,1);
cout<<ans;
}
//# 奇怪的电梯
//
//## 题目描述
//
//呵呵,有一天我做了一个梦,梦见了一种很奇怪的电梯。大楼的每一层楼都可以停电梯,而且第 $i$ 层楼($1 \le i \le N$)上有一个数字 $K_i$($0 \le K_i \le N$)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: $3, 3, 1, 2, 5$ 代表了 $K_i$($K_1=3$,$K_2=3$,……),从 $1$ 楼开始。在 $1$ 楼,按“上”可以到 $4$ 楼,按“下”是不起作用的,因为没有 $-2$ 楼。那么,从 $A$ 楼到 $B$ 楼至少要按几次按钮呢?
//
//## 输入格式
//
//共二行。
//
//第一行为三个用空格隔开的正整数,表示 N, A, B(
//
//第二行为 $N$ 个用空格隔开的非负整数,表示 Ki。
//
//## 输出格式
//
//一行,即最少按键次数,若无法到达,则输出 `-1`。
//
//## 样例 #1
//
//### 样例输入 #1
//
//```
//5 1 5
//3 3 1 2 5
//```
//
//### 样例输出 #1
//
//```
//3
//```
//
//## 提示
//1<=N<=200
}
思路:这个题如果使用dfs的话时间会超限,要使用bfs,要注意判断的时候,一个点我们可能会走多次,所以说我们需要去判断那个地方是不是走过,因为是bfs所以说只要是第一次走过便是最短的次数,我们只需要第一次走过这个点时的步数就可以了,主要就是把每个地方能到的可能全部都存储起来,最后只要输出题目要求的地点的步数就可以了
#include<bits/stdc++.h>
using namespace std;
struct floors{
int up,down,step;
int v;
}fs[205];
int main()
{
int n,a,b,tmep;
cin>>n>>a>>b;
for(int i=1;i<=n;i++)
{
cin>>tmep;
fs[i].up=i+tmep;
fs[i].down=i-tmep;
fs[i].step=-1;
fs[i].v=0;
}
fs[a].step=0,fs[a].v=1;
queue<floors>q;
q.push(fs[a]);
while(!q.empty())
{
floors f=q.front();
q.pop();
int u=f.up,d=f.down;
if(u>=1&&u<=n&&fs[u].v==0)
{
fs[u].v=1;
fs[u].step=f.step+1;
q.push(fs[u]);
}
if(d>=1&&d<=n&&fs[d].v==0)
{
fs[d].v=1;
fs[d].step=f.step+1;
q.push(fs[d]);
}
if(u==b||d==b)
break;
}
cout<<fs[b]