九度 1035 并查集相关

             题目1035:找出直系亲属

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:1738

解决:706

题目描述:
    如果A,B是C的父母亲,则A,B是C的parent,C是A,B的child,如果A,B是C的(外)祖父,祖母,则A,B是C的grandparent,C是A,B的grandchild,如果A,B是C的(外)曾祖父,曾祖母,则A,B是C的great-grandparent,C是A,B的great-grandchild,之后再多一辈,则在关系上加一个great-。
输入:
    输入包含多组测试用例,每组用例首先包含2个整数n(0<=n<=26)和m(0<m<50), 分别表示有n个亲属关系和m个问题, 然后接下来是n行的形式如ABC的字符串,表示A的父母亲分别是B和C,如果A的父母亲信息不全,则用-代替,例如A-C,再然后是m行形式如FA的字符串,表示询问F和A的关系。
    当n和m为0时结束输入。
输出:
    如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。
    具体含义和输出格式参见样例.
样例输入:
3 2
ABC
CDE
EFG
FA
BE
0 0
样例输出:
great-grandparent
-
来源:
2009年浙江大学计算机及软件工程研究生机试真题

题目大意: 这里就不用说了中文的 大家都能懂的
解题思路: 一看 会觉得的这个题要么和二叉树的树形结构有些关系 ,但是呢 如果用二叉树又不太好处理 , 正好有一种方式 和这道题很像 那就是并查集:
  首先,题目问的是最后两者的关系 父子关系还是 什么关系什么的 ,那和并查集里面查找两者的关系很相似 ,在于什么呢,在于要记录多少代问题,这里给出了一种用计数的方式解决
其次: 输入时输入两个 或者三个字母, 表示他们之间的关系,因此 现在就是要把他们的关系整合一下 ,这个和并查集里面 的union很像 因此就行到用并查集相关问题解决了。。。

下面给出代码: 细节部分会在代码里面给出说明
最近有点小忙, 虽然每天坚持写代码,但是效率不是很高,可能是最近太累了吧,我会努力调整到最佳状态,每天以最阳光,最有效率的一面去生活!
好吧这道题纠结了我好几天 ,一直找bug 一直没找到, 后然看了下别人的博客 修改了下,已经成功ac
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;

int child[30];//表示孩子的数目
int find(int x , int y)
{
     int res = -1;//用来记录一共多少代
     while(child[x] != -1)
     {
        if(child[x] == y)
        {
            break;//他们是父子关系找到了,循环结束
        }
        x = child[x];
        res++;//
     }
     //这里是用循环进行求解的 也可以用递归进行求解,不过就是会麻烦一些
     //经过上面的循环,一定会出现两种结果要么找到他们之间有关系,要么么他们之间没有任何关系
     if(child[x]== y)
     {
         return res;
     }
     else
     {
         return -1;
     }
}
int main()
{
    //下面是主函数的输入和输出
    //这里主要是对字符串的处理和初始换函数
    int m , n;
    while(cin>>m>>n)
    {
        char buf[5] ;
        if(m == 0 && n == 0) return 0;
        memset(child, -1,  sizeof(child));
        for(int i = 0 ; i < m ; i++)
        {
            //下面开始进行初始化
            scanf("%s", buf);
            int tmp = buf[0] -'A';
            if(buf[1] !='-')
            {//将符号转换为整数
                int tmp1 = buf[1] -'A';
                child[tmp1] = tmp;
            }
            if(buf[2] != '-')
            {
                int tmp2 = buf[2] -'A';
                child[tmp2] = tmp;
            }
        }
        for(int j = 0 ; j < n ;j++)
        {
            scanf("%s", buf);
            int tmp3 = buf[0] - 'A';
            int tmp4 = buf[1] - 'A';
            int ans1 = find(tmp3, tmp4);//表示的是tmp3 和tmp4 的关系还有一种情况是tmp4和tmp3关系
            int ans2 = find(tmp4, tmp3);
            if(ans1 == -1 && ans2 == -1)
            {
                printf("-\n");
            }
            else if(ans1 != -1)
            {//这里需要表你如果他们之间没有关系
               //如果ans1为正的, tmp3 是祖先

               switch(ans1)
               {//只有那么几种关系 parent great-grandparent
                  case 0:
                  printf("parent\n");
                      break;
                   default:
                    for(int k = 0 ; k < ans1; k++)
                    {
                        printf("great-");
                    }
                    printf("grandparent\n");
                    break;
               }

            }
            else if (ans2 != -1)
            {

                    switch(ans2)
                    {//因为是从-1 开始的,因此+1 那么就是0了
                        case 0:
                            printf("child\n");
                            break;
                        default:
                            for(int k = 0 ; k < ans2; k++)
                            {
                                printf("great-");
                            }
                            printf("grandchild\n");
                            break;
                    }
            }
        }
    }
    return 0;
}




wangxiaoming CSDN认证博客专家 架构 Spring Boot Redis
博客是很好的总结和记录工具,如果有问题,来不及回复,关注微信公众号:程序员开发者社区,获取我的联系方式,向我提问,也可以给我发送邮件,联系 1275801617@qq.com
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值