IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 题解——Lowest Common Ancestor(16进制LCA) -> 正文阅读

[数据结构与算法]题解——Lowest Common Ancestor(16进制LCA)

Perfect binary trees are one of the coolest structures that computer scientists study. They have a lot of properties that make them very nice to work with. One of the nicest properties is that they can just be described by a single integerngiving the depth of the tree. For instance, the perfect binary tree forn= 3 looks like:

In general, a perfect binary tree with depthnwill have exactly 2n+1?– 1 nodes, and can be numbered by following the pattern seen above (there are of course other ways to number the nodes of the tree, but this is the scheme we will use in this problem).

A common question that arises when dealing with trees is the query of the lowest common ancestor (commonly called LCA) of two nodes in the tree. Formally, the LCA ofxandyis the nodezof greatest depth in the tree such thatzis an ancestor ofxandy. Nodeais an ancestor of nodecifcexists in the sub-tree rooted at nodea. Notice that 1 is trivially a common ancestor of any two nodes in the tree, but is not always thelowestcommon ancestor. For instance, the common ancestors of nodes 7 and 12 are 1 and 3, and 3 is the LCA since it is the node of greatest depth. The LCA of 2 and 13 is node 1, and the LCA of 5 and 11 is node 5. The definition of LCA guarantees that the LCA of any two nodes will always be unique.

The Problem:

Given two nodes in the tree using the numbering scheme shown above, determine the LCA of the two nodes.

完美二叉树是计算机科学家研究的最酷的结构之一。它们有很多特性,使它们非常适合使用。最好的属性之一是它们只能通过一个整数来描述树的深度。例如,forn=3 的完美二叉树看起来像:

一般来说,一个具有depthn的完美二叉树将恰好有2n+1-1个节点,并且可以按照上面看到的模式进行编号(当然还有其他方法来对树的节点进行编号,但这是我们将要使用的方案在这个问题中使用)。

处理树时出现的一个常见问题是查询树中两个节点的最低公共祖先(通常称为 LCA)。正式地,xandyi 的 LCA 是树中最大深度的节点,因此这是 xandy 的祖先。 Nodeai 是 nodecifc 的祖先,存在于以 nodea 为根的子树中。请注意,1 是树中任何两个节点的共同祖先,但并不总是最低的共同祖先。例如,节点 7 和 12 的共同祖先是 1 和 3,而 3 是 LCA,因为它是最大深度的节点。 2和13的LCA是节点1,5和11的LCA是节点5。LCA的定义保证了任意两个节点的LCA永远是唯一的。

问题:

使用上面显示的编号方案给定树中的两个节点,确定这两个节点的 LCA。

输入描述:

输入以一个正整数开始,T≤ 2?106,表示测试用例的数量。 接下来是测试案例,每个案例都在单独的输入行上。 每个测试用例将包含两个空格分隔的整数 X 和 Y,以十六进制表示。 XandY 每个将包含来自集合 {0,1,2,3,4,5,6,7,8,9,a,b,c 的最多 1000 个字符 ,d,e,f},其中 a-frepresent 分别为 10-15。 您要确定 X 和 Y 的 LCA。 注:十六进制(基数为16)数dndn-1...d1d0通过以下公式转换为十进制数(基数为10):d0·160 +d1·161 +... +dn-1·16n-1 +dn ·16n。

输出描述:

对于每种情况,输出单行:

Case#x:y

其中xi是从1开始的案例编号,y是十六进制的LCA,没有前导0。 在每个测试用例的输出后留一个空行。

链接:https://ac.nowcoder.com/acm/contest/18480/J
来源:牛客网
?

输入

7
7 c
2 d
b 5
10 11
a020fac a030ccf
12afcdb 12afcdc
100000000 fffffffff

输出

Case #1: 3

Case #2: 1

Case #3: 5

Case #4: 8

Case #5: 501

Case #6: 255f9b

Case #7: 1

思路

众所周知,LCA需要遍历所有点确定其深度才能求出,但是在这个题里,这样做的成本非常大。因为这里每个数都是16进制数,而且还是高精数,这导致我们想要遍历整个完全树是不可能的。

因此,我苦思冥想,想到了一种可以不用转换进制也不需要遍历的方法。

我们先写一个函数比较X和Y的大小,然后将其中那个较大的数除以2,如果反复这样做,无论两个数是否在同一层,他们都会回到同一个节点(这个时候两数相等),这个节点就是他们的最大公共祖先。

代码量还是比较大的,毕竟是高精的LCA。

#include <iostream>
#include <cstring>
using namespace std;
 
char X[1001],Y[1001];
int x[1001],y[1001],l1,l2;
 
 
int power()// 比较两高精数的大小
{
    if(l1>l2) return 1;
    if(l1<l2) return -1;
    for(int i=l1;i>0;i--)
    {
        if(x[i]>y[i]) return 1;
        if(x[i]<y[i]) return -1;
    }
    return 0;
}
void change()
{
    int bo=1;
    while(bo!=0)//当X=Y时,说明此时两点都回到了他们的最大公共祖先处
    {
        bo=power();
        if(bo==1)//如果X>Y,就将X除以2
        {
            for(int i=l1;i>0;i--)
            {
                if(x[i]%2==1) x[i-1]+=16;
                x[i]/=2;
            }
            if(x[l1]==0) l1--;
        }
        if(bo==-1)//如果X<Y,就将Y除以2
        {
            for(int i=l2;i>0;i--)
            {
                if(y[i]%2==1) y[i-1]+=16;
                y[i]/=2;
            }
            if(y[l2]==0) l2--;
        }
    }
}
int main()
{
    int t;
    cin>>t;
    for(int i0=1;i0<=t;i0++)
    {
        scanf("%s%s",&X,&Y);
        l1=strlen(X);
        l2=strlen(Y);
        for(int i=0;i<l1;i++)
        {
            if(X[i]<='9'&&X[i]>='0')
            {
                x[l1-i]=X[i]-'0';
            }
            else
            {
                x[l1-i]=10+X[i]-'a';
            }
        }
        for(int i=0;i<l2;i++)
        {
            if(Y[i]<='9'&&Y[i]>='0')
            {
                y[l2-i]=Y[i]-'0';
            }
            else
            {
                y[l2-i]=10+Y[i]-'a';
            }
        }

        change();

        cout<<"Case #"<<i0<<": ";
        for(int i=l1;i>=1;i--)
        {
            if(x[i]>=10) cout<<char('a'+x[i]-10);
            else cout<<x[i];
        }
        if(i0<t) cout<<endl;
        cout<<endl;
        memset(x,0,sizeof(x));
        memset(y,0,sizeof(y));
    }
    return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-16 22:03:18  更:2021-07-16 22:03:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 10:30:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计