九度 1035 并查集相关

来源:互联网 发布:朝鲜和韩国知乎 编辑:程序博客网 时间:2024/06/15 21:44
            
题目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 2ABCCDEEFGFABE0 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;}




0 0