题目描述
如果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的关系。
输出描述:
如果询问的2个人是直系亲属,请按题目描述输出2者的关系,如果没有直系关系,请输出-。 具体含义和输出格式参见样例.
示例1
输入
3 2 ABC CDE EFG FA BE
输出
great-grandparent -
注意
该题被王道归为并查集题目,但是我觉得直接用map容器来做就搞定了,而且简单很多。
代码
#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
using namespace std;
map<char,char> son;
map<char,int> priority;//用来标记优先级,优先级越高代表是祖先
void Initial()//初始化
{
char a='A';
while(a!='Z'+1)
{
son[a]='*';
priority[a]=0;
a++;
}
}
int check(char A,char B)
{
if(priority[A]>priority[B])//A是祖先
{
int num=0;
while(A!='*')
{
num++;
A=son[A];
if(A==B)
break;
}
if(A!='*')
return num;
else
return 0;
}
else{ //A是子孙
int num=0;
while(B!='*')
{
num--;
B=son[B];
if(B==A)
break;
}
if(B!='*')
return num;
else
return 0;
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
Initial();
int p=0;
while(n--)
{
string str;
cin>>str;
p++;
for(int i=1;i<=2;i++)
{
if(str[i]!='-')
son[str[i]]=str[0];
priority[str[i]]=p;
}
}
while(m--)
{
string str2;
cin>>str2;
int u=check(str2[0],str2[1]);
if(u==0)
cout<<'-'<<endl;
else if(u>0)
{
if(u==1)
cout<<"parent"<<endl;
else if(u==2)
cout<<"grandparent"<<endl;
else if(u>=3)
{
while(u!=3)
{
cout<<"great-";
u--;
}
cout<<"great-grandparent"<<endl;
}
}
else
{
if(u==-1)
cout<<"child"<<endl;
else if(u==-2)
cout<<"grandchild"<<endl;
else if(u<=-3)
{
while(u!=-3)
{
cout<<"great-";
u++;
}
cout<<"great-grandchild"<<endl;
}
}
}
}
return 0;
}