寒假刷题第20天

文章讲述了在C++中使用递归和unordered_map数据结构实现二叉树的最近公共祖先(LCA)算法,以及处理两个节点查找和错误处理的情况。两个示例代码分别对应题目1143和1151,涉及了树的遍历和逻辑判断。
摘要由CSDN通过智能技术生成

PTA甲级

1143 Lowest Common Ancestor

#include<iostream>
#include<algorithm>
#include<unordered_map>

using namespace std;

const int N = 1e5 + 10;
int n , m;
int pre[N] , in[N] , depth[N];
int l[N] , r[N];
unordered_map<int , int>last , idx;

int build(int il , int ir , int pl , int pr , int dep)
{
    int root = pre[pl];
    int k = idx[root];
    depth[root] = dep;

    if(il < k)
    {
        l[root] = build(il , k - 1 , pl + 1 , k - il + pl , dep + 1);
        last[l[root]] = root;
    }
    if(ir > k)
    {
        r[root] = build(k + 1 , ir , k - il + pl + 1 , pr , dep + 1);
        last[r[root]] = root;
    }
    return root;
}

int main()
{
    cin >> m >> n;
    for(int i = 0;i < n;i ++)
        cin >> pre[i] , in[i] = pre[i];

    sort(in , in + n);
    for(int i = 0;i < n;i ++)
        idx[in[i]] = i;

    int root = build(0 , n - 1 , 0 , n - 1 , 0);
    while(m --)
    {
        int a , b;
        cin >> a >> b;
        if(idx.count(a) && idx.count(b))
        {
            int x = a , y = b;
            while(a != b)
            {
                //谁深谁往上走,直到找到一样的节点是就退出
                if(depth[a] > depth[b]) a = last[a];
                else b = last[b];
            }
            if(x != a && y != a) printf("LCA of %d and %d is %d.\n", x, y, a);
            else if(x == a) printf("%d is an ancestor of %d.\n", x , y);
            else printf("%d is an ancestor of %d.\n", y , x);
        }
        else if(!idx.count(a) && !idx.count(b))
            printf("ERROR: %d and %d are not found.\n" ,a ,b);
        else if(!idx.count(b)) 
            printf("ERROR: %d is not found.\n" , b);
        else 
            printf("ERROR: %d is not found.\n" , a);
    }
    return 0;
}

1151 LCA in a Binary Tree

#include<iostream>
#include<algorithm>
#include<unordered_map>

using namespace std;

const int N = 1e6 + 10;
int n , m;
int pre[N] , in[N] , depth[N];
int l[N] , r[N];
unordered_map<int , int>last , idx;

int build(int il , int ir , int pl , int pr , int dep)
{
    int root = pre[pl];
    int k = idx[root];
    depth[root] = dep;

    if(il < k)
    {
        l[root] = build(il , k - 1 , pl + 1 , k - il + pl , dep + 1);
        last[l[root]] = root;
    }
    if(ir > k)
    {
        r[root] = build(k + 1 , ir , k - il + pl + 1 , pr , dep + 1);
        last[r[root]] = root;
    }
    return root;
}

int main()
{
    cin >> m >> n;
    for(int i = 0;i < n;i ++) cin >> in[i] , idx[in[i]] = i;
    for(int i = 0;i < n;i ++) cin >> pre[i];

    int root = build(0 , n - 1 , 0 , n - 1 , 0);
    while(m --)
    {
        int a , b;
        cin >> a >> b;
        if(idx.count(a) && idx.count(b))
        {
            int x = a , y = b;
            while(a != b)
            {
                //谁深谁往上走,直到找到一样的节点是就退出
                if(depth[a] > depth[b]) a = last[a];
                else b = last[b];
            }
            if(x != a && y != a) printf("LCA of %d and %d is %d.\n", x, y, a);
            else if(x == a) printf("%d is an ancestor of %d.\n", x , y);
            else printf("%d is an ancestor of %d.\n", y , x);
        }
        else if(!idx.count(a) && !idx.count(b))
            printf("ERROR: %d and %d are not found.\n" ,a ,b);
        else if(!idx.count(b)) 
            printf("ERROR: %d is not found.\n" , b);
        else 
            printf("ERROR: %d is not found.\n" , a);
    }
    return 0;
}

1148 Werewolf - Simple Version

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int n;
vector<int>v(n + 10);

int main()
{
    cin >> n;
    for(int i = 1;i <= n;i ++) cin >> v[i];

    for(int i = 1;i <= n;i ++)
    {
        for(int j = i + 1;j <= n;j ++)
        {
            vector<int>v1(n + 10 , 1); //该人是狼人还是好人 等于1表示是好人,等于-1表示是狼人
            vector<int>v2;
            v1[i] = v1[j] = -1;
            for(int k = 1;k <= n;k ++)
                if(v[k] * v1[abs(v[k])] < 0) v2.push_back(k);
            if(v2.size() == 2 && v1[v2[0]] + v1[v2[1]] == 0) // 说谎人数等于2并且这两个说谎的人一个是好人一个是狼人
            {
                cout << i << " " << j << endl;
                return 0;
            }
        }
    }
    puts("No Solution");
    return 0;
}

补牛客寒假第一次

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值