第五次总结

想了想,主要是有个题感觉怪怪的,今天还是弄两个其他的题吧

//# 【深基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]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值