ZJU 09 复试上机 第五题

来源:互联网 发布:微信企业号java 编辑:程序博客网 时间:2024/05/29 05:07

第五题: 找出直系亲属。如果ABC的父母亲,则ABCparentCABchild,如果ABC的(外)祖父,祖母,则ABCgrandparentCABgrandchild,如果ABC的(外)曾祖父,曾祖母,则ABCgreat-grandparentCABgreat-grandchild,之后再多一辈,则在关系上加一个great-

输入:n0<=n<=26)表示n个亲属关系,形式为ABC,表示A的父母亲分别是BC,如果A的父母亲信息不全,则用-代替,例如A-Cm(。。。)代表测试用例数,形式AB。输出:AB的关系,如AB的直系亲属,按上述要求输出关系,如果AB没有关系,输出-。当n0时结束。

 

Input

3 2

ABC

CDE

EFG

FA

BE

0 0

 

Output:

great-grandparent

这道题目重点之一在于信息的组织,因为任意一个节点有两个双亲,而儿女个数不是确定的,因此没法使用一般的树结构来组织信息,图结构不能反映层次关系 更加不好处理,可以采用静态链表的方案 发现这种方案在这种小型算法程序中比较好用 位置指针便于使用 也避免繁琐的指针细节  接下来就是沿着这个节点位置向祖先路径上遍历,访问时检查是否匹配,一旦查找到就立刻结束,使用tag作为深度展开的入口检查条件,因为只能访问祖先,调换顺序 再访问一次,如果还未找到不要忽略了二者可能是兄弟结点(这里题目不是很清,要注意陷阱),最后的分支是输出二者没有任何关系

总结

重点在于三点

1.选择合适的组织信息方案;

2,开始时记得把所有的结点标记为空(-1),以便作为递归终止标识//注意开始犯的错误,只初始到n

3,熟悉搜索框架,进行必要的剪枝

//一开始犯了一个错误,n只是关系的数目,而不是结点编号的最大值,所以调试的时候出现异常,因为所有后面未能初始化的结点都被默认初始化为0,即为A的孩子

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int tag,level;

int convert(char c)
{
 return c-'A';
}

struct node
{
 int father,mother;//直接转换为编号,不用字母
};

node record[30];

void search(int from,int to,int count)
{
 if(record[from].mother==to||record[from].father==to)
 {
  level=count;
  tag=0;//标记,结束探查 减枝;
  return;
 }
 if(record[from].mother!=-1&&tag)search(record[from].mother,to,count+1);
 if(record[from].father!=-1&&tag)search(record[from].father,to,count+1);
}

 

int main()
{
 int n,m;
 while(cin>>n>>m&&n)
 {
  int i;
  for(i=0;i<26;i++)//因为不可能穷极所有的父母信息,所以初始化为未知是最方便的以后作为遍历终止条件
   record[i].mother=record[i].father=-1;//没说编号规则,这里改成26更好一点
   
  string input;
  for(i=0;i<n;i++)
  {
   cin>>input;
   int number;
   number=convert(input[0]);
   if(input[1]!='-')record[number].father=convert(input[1]);
   if(input[2]!='-')record[number].mother=convert(input[2]);
  }
  while(m--)
  {
   char from,to;
   cin>>from>>to;
   tag=1;
   search(convert(from),convert(to),0);
   if(!tag)//找到,to为from的祖先
   {
    if(level==0)cout<<"child"<<endl;
    else if(level==1)cout<<"grandchild"<<endl;
    else
    {
     while(level>1)cout<<"great-",level--;
     cout<<"grandchild"<<endl;
    }
    continue;
   }
   tag=1;
   search(convert(to),convert(from),0);
   if(!tag)//找到,from为to的祖先
   {
    if(level==0)cout<<"parent"<<endl;
    else if(level==1)cout<<"grandparent"<<endl;
    else
    {
     while(level>1)cout<<"great-",level--;
     cout<<"grandparent"<<endl;
    }
    continue;
   }
   //注意要考虑二者是不是兄弟,这里就不考虑单亲相同了
   int v1=convert(from);
   int v2=convert(to);
   if((record[v1].mother==record[v2].mother)&&(record[v1].father==record[v2].father))
   {
    cout<<"brother"<<endl;
    continue;
   }
   cout<<"-"<<endl;//unknow relationship

  }
 }
 return 0;
}

原创粉丝点击