【連結串列】找出直系親屬
阿新 • • 發佈:2021-02-07
技術標籤:機試
題目描述
如果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 -
其實本質相當於倒過來的二叉樹
比如題目中的例子
A是BC的孩子,那麼應該建立由B向A的連結串列和由C向A的連結串列,這樣的目的是從任何一個節點向下遍歷方向是唯一的,容易確定先後順序
比如我想知道G和C是不是直系親屬,那麼從G遍歷下來的路徑是GECA,這裡麵包含了C,所以G是C的爺爺(因為隔了兩代)
如果判斷G和D是不是直系親屬,從G向下遍歷是GECA,從D遍歷下來時DCA,注意,雖然有交集CA,但由於G的遍歷中不含有D,D的遍歷中不含有G,所以兩者不是直接親屬
基於以上的思想,我們可以開一個map分別記錄每一個人的指標,之後開一個vector,記錄每人向下遍歷的路徑。
之後比如想知道B和G的關係,首先根據map找到B指標,根據指標找到vector中B的遍歷路徑,查詢是否有G。如果有的話,證明B是G的前輩,按照代數輸出parent即可。
如果沒有,則反過來根據map找到G的指標,根據指標找到vector中G的遍歷路徑,查詢是否有B,如果有證明B是G的孩子,根據代數輸出child即可。
若也沒有,則為-,即不是直系親屬
總結:是一道連結串列的好題目
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#include<cstring>
#include <sstream>
#include<map>
using namespace std;
struct data{
char id;
data* child;
data(char id):id(id),child(NULL){}
};
int find(vector<char> v,char text){
for(int i=0;i<v.size();i++){
if(v[i]==text){
return i;
}
}
return -1;
}
map<char,data*>mp;
int main(){
int num,ques;
cin>>num>>ques;
mp.clear();
for(char i='A';i<='Z';i++)
mp[i]=NULL;
while(num--){
char a[3];
cin>>a;
data* p1=mp[a[1]];
data* p2=mp[a[2]];
//如果map中沒有這個人的指標位置,則需要存入map
//如果已經有了,即p1!=NULL時,表明之前已經存入map了,不用再次儲存
if(p1==NULL){
p1=new data(a[1]);
mp[a[1]]=p1;
}
if(p2==NULL){
p2=new data(a[2]);
mp[a[2]]=p2;
}
data* p0=mp[a[0]];
if(p0==NULL){
p0=new data(a[0]);
mp[a[0]]=p0;
}
//如果缺少父母資訊,則不存入資料
if(a[1]!='-')
p1->child=p0;
if(a[2]!='-')
p2->child=p0;
}
vector<char>v[26];
//記載每一個人的遍歷路徑,比如vector[0]表明A從上到下的遍歷路徑
for(int i=0;i<26;i++){
data* now=mp['A'+i];
while(now!=NULL){
v[i].push_back(now->id);
now=now->child;
}
}
while(ques--){
char temp[2];
cin>>temp;
char s1=temp[0];
char s2=temp[1];
int ans=find(v[s1-'A'],s2);
if(ans==-1){//從s1到s2找不到時,倒過來找試試,因為s1不是s2的前輩時,有可能s1是s2的後輩
ans=find(v[s2-'A'],s1);
if(ans==-1){//既不是前輩也不是後輩,則不是直系親屬
cout<<"-"<<endl;
}
else if(ans==1)
cout<<"child"<<endl;
else if(ans==2)
cout<<"grandchild"<<endl;
else {
for(int i=1;i<=ans-2;i++)
cout<<"great-";
cout<<"grandchild"<<endl;
}
}
else{
if(ans==1)
cout<<"parent"<<endl;
else if(ans==2)
cout<<"grandparent"<<endl;
else{
for(int i=1;i<=ans-2;i++)
cout<<"great-";
cout<<"grandparent"<<endl;
}
}
}
}