• UVALive 7291 Kinfolk(最近公共祖先)


      题目中的描述就很最近公共祖先,再说其实这个题并不难,就是麻烦点(代码其实可以化简的),我写的判定比较多。

      方法;求出两者的最近公共祖先lca,在求出两者到lca的距离

      分析:给出a和b,如果LCA(a,b) == a或者b,那他们肯定是直系的,是父子,爷孙之类的关系。

         如果LCA(a,b)> a 和 b,假如说a的辈分高(使用深度代表辈分),且disa = 1,那么他们是叔叔,侄子之类的关系

         再者就是堂姐堂弟的关系了,代码里解释的比较详细,代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define N 32767
    struct Node
    {
        int l,r,pa,deep;
    } node[N+10];
    void dfs(int x,int d)
    {
        if(x > N) return;
        node[x].l = x*2+1;
        node[x].r = x*2+2;
        node[x].deep = d;
        if(x==0) node[x].pa = x;
        else if(x%2==0) node[x].pa = x/2-1;
        else node[x].pa = x/2;
        dfs(node[x].l,d+1);
        dfs(node[x].r,d+1);
    }
    int LCA(int a,int b)
    {
        while(node[a].deep > node[b].deep)
        {
            a = node[a].pa;
        }
        while(node[b].deep > node[a].deep)
        {
            b = node[b].pa;
        }
        while(a != b)
        {
            a = node[a].pa;
            b = node[b].pa;
        }
        return a;
    }
    int main()
    {
    //    freopen("A.in.cpp","r",stdin);
        dfs(0,1);///预处理每一个节点的父亲和深度
        int a,b,lca,disa,disb;
        string tmp;
        char gender;
        while(~scanf("%d %d %c",&a,&b,&gender))
        {
            if(a==-1 && b==-1) break;
            lca = LCA(a,b);///求出lca和距离
            disa = node[a].deep - node[lca].deep;
            disb = node[b].deep - node[lca].deep;
    //        printf("LCA(%d,%d) = %d
    ",a,b,lca);
    //        printf("lca - deep = %d
    ",node[lca].deep);
    //        printf("disa = %d  disb = %d
    ",disa,disb);
            if(a == b) printf("self
    ");
            else if(disa == disb && disa == 1)///姐弟关系
            {
                if(gender == 'F') printf("sister
    ");
                else printf("brother
    ");
            }
            else if(lca == a)///直系关系
            {
                if(gender == 'F') tmp = "daughter";
                else tmp = "son";
                if(disb == 1)
                    cout<<tmp<<endl;
                else if(disb == 2) cout<<"grand"<<tmp<<endl;
                else if(disb == 3) cout<<"great-grand"<<tmp<<endl;
                else if(disb == 4) cout<<"great-great-grand"<<tmp<<endl;
                else printf("kin
    ");
            }
            else if(lca == b)
            {
                if(gender == 'F') tmp = "mother";
                else tmp = "father";
                if(disa == 1)
                    cout<<tmp<<endl;
                else if(disa == 2) cout<<"grand"<<tmp<<endl;
                else if(disa == 3) cout<<"great-grand"<<tmp<<endl;
                else if(disa == 4) cout<<"great-great-grand"<<tmp<<endl;
                else printf("kin
    ");
            }
            else if(node[a].pa == lca && node[a].deep < node[b].deep)///叔侄关系
            {
                if(gender == 'F') tmp = "niece";
                else tmp = "nephew";
                if(disb == 2)
                    cout<<tmp<<endl;
                else if(disb == 3) cout<<"grand"<<tmp<<endl;
                else if(disb == 4) cout<<"great-grand"<<tmp<<endl;
                else if(disb == 5) cout<<"great-great-grand"<<tmp<<endl;
                else printf("kin
    ");
            }
            else if(node[b].pa == lca && node[a].deep > node[b].deep)
            {
                if(gender == 'F') tmp = "aunt";
                else tmp = "uncle";
                if(disa == 2)
                    cout<<tmp<<endl;
                else if(disa == 3) cout<<"grand"<<tmp<<endl;
                else if(disa == 4) cout<<"great-grand"<<tmp<<endl;
                else if(disa == 5) cout<<"great-great-grand"<<tmp<<endl;
                else printf("kin
    ");
            }
            else if(disa >= 2 && disb >= 2)///堂姐堂弟
            {
                tmp = "cousin";
                int Max = max(disa,disb);
                int Min = min(disa,disb);
                int cha = Max - Min;///这个差帮助我们判定后代
                if(Min <= 4 && cha <= 3)
                {
                    if(Min == 2) cout<<"1st "<<tmp;
                    else if(Min == 3) cout<<"2nd "<<tmp;
                    else if(Min == 4) cout<<"3rd "<<tmp;
                    if(cha == 0) cout<<endl;
                    else if(cha == 1) cout<<" once removed"<<endl;
                    else if(cha == 2) cout<<" twice removed"<<endl;
                    else if(cha == 3) cout<<" thrice removed"<<endl;
                }
                else cout<<"kin"<<endl;
            }
            else cout<<"kin"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    大白话解说,半分钟就懂 --- 分布式与集群是什么 ? 区别是什么?
    intellij idea中去除@Autowired注入对象的红色波浪线提示
    用JQuery获取事件源怎么写
    springBoot 配置url 访问图片
    地图服务 纬度、经度对应坐标轴x,y
    5个问题带你了解export和import的使用以及export和export defalut 的区别
    5个你可能不知道的html5语义化标签
    CSS选择器[attribute | = value] 和 [attribute ^ = value]的区别
    前端ps实用小技巧
    7步教你使用git命令上传本地代码至github仓库(小白向)
  • 原文地址:https://www.cnblogs.com/jifahu/p/5746042.html
Copyright © 2020-2023  润新知