一、题目描述
如果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存每个char对应的树节点指针。再向上或向下查询该树便可。(注释详细)
注意点:
1.每次使用指针时应该考虑是否为NULL
2.用char数组接收输入时应该多一位结束位,如输入ab应该用size为3的数组。
3.几种接收输入的方式:cin.get(字符数组名,接收字符数);cin.getline(接受字符串到m,接受个数5,结束字符),第三个参数默认为\0;cin>>;
#include <iostream>
#include <string>
#include <vector>
#include <map>
using namespace std;
// 思路:构建树,搜索。用map存每个树结点的指针
// 结构体的初始化函数
typedef struct node {
char value;
node* fa;
node* mo;
vector<node*> child;
node(char va, node* f, node* m) {
this->value = va;
this->fa = f;
this->mo = m;
}
}node;
// 向上搜索,返回辈分差,若都找不到,返回-1
int searchUp(node* cur, node* obj) {
//没找到
if (cur == NULL) {
return -1;
}
//找到了
else if (cur->value == obj->value) {
return 0;
}
else {
int temp = searchUp(cur->fa, obj);
int temp0 = searchUp(cur->mo, obj);
if (temp != -1)
return temp + 1;
if (temp0 != -1)
return temp0 + 1;
return -1;
}
}
// 向下搜索,返回辈分差,若都找不到,返回-1
int searchDown(node* cur, node* obj) {
//没找到
if (cur == NULL) {
return -1;
}
//找到了
else if (cur->value == obj->value) {
return 0;
}
else {
int res;
for (int i = 0; i < cur->child.size();i++) {
res = searchDown(cur->child[i], obj);
//找到了
if (res != -1)
return res + 1;
}
//没找到
return -1;
}
}
int main() {
int x, y;
cin >> x >> y;
//接收每行输入,构建树,默认结点名不重复
char temp[4];
//ma存char与结点指针的映射
map<char, node*> ma;
for (int i = 0;i < x;i++) {
cin >> temp;
//构建三个节点,记录在ma中,有结点可能已经存在,tempnode分别为child,father,mother
node* tempnode[3];
for (int j = 0;j < 3;j++) {
if (temp[j] == '-') {
tempnode[j] = NULL;
continue;
}
if (ma.find(temp[j]) != ma.end()) {
tempnode[j] = ma[temp[j]];
}
else {
tempnode[j] = new node(temp[j], NULL, NULL);
ma[temp[j]] = tempnode[j];
}
}
//建立连接
tempnode[0]->fa = tempnode[1];
tempnode[0]->mo = tempnode[2];
//使用指针时记得考虑是否为NULL
if(tempnode[1]!=NULL)
tempnode[1]->child.emplace_back(tempnode[0]);
if(tempnode[2]!=NULL)
tempnode[2]->child.emplace_back(tempnode[0]);
}
//查找树
char temp0[3];
node* first;
node* second;
int res;
string resstr;
for (int i = 0;i < y;i++) {
cin >> temp0;
// 从第一个结点开始向上或向下搜索
//向上搜索
first = ma[temp0[0]];
second = ma[temp0[1]];
res = searchUp(first, second);
// 搜到了
if (res != -1) {
resstr = "child";
res -= 1;
if (res >= 1) {
resstr = "grand" + resstr;
res -= 1;
}
for (int j = 0;j < res;j++) {
resstr = "great-" + resstr;
}
cout << resstr<<"\n";
}
// 没搜到
else {
// 向下搜索
res = searchDown(first, second);
//没搜到
if (res == -1) {
cout << "-"<<"\n";
}
else {
resstr = "parent";
res -= 1;
if (res >= 1) {
resstr = "grand" + resstr;
res -= 1;
}
for (int j = 0;j < res;j++) {
resstr = "great-" + resstr;
}
cout << resstr<<"\n";
}
}
}
return 0;
}