本题保证了不会出现同名的人,因此只需要保存名不需要保存姓,姓作为一个父亲结点保存,用map保存名所对应的编号,father数组保存父亲结点,然后用两个循环找寻结点,无奈最后一个测试点超时了,欢迎各位大佬指正
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
vector<string>father;
map<string,int>m;
vector<int>sex;//1m0f
string find(string s){
while(m.find(s)!=m.end()){
int v=m[s];
s=father[v];
}
return s;
}//没想到加了这个函数还是超时了
bool judge(string a,string b){
if(find(a)!=find(b)) return true;
int i,j;
string s1,s2;
for(i=1,s1=a; m.find(s1)!=m.end(); i++,s1=father[m[s1]]){
for(j=1,s2=b; m.find(s2)!=m.end(); j++,s2=father[m[s2]]){
if(i>=5&&j>=5) return true;
if(s1==s2&&(i<5||j<5)) return false;
}
}
return true;//如果代数很短 直接返回true
}//只用这个函数会超时
int main(){
int n;
cin>>n;
sex.resize(n);
father.resize(n);
for(int i=0;i<n;i++){
string firstname,lastname;
cin>>firstname>>lastname;
m[firstname]=i;
int len=lastname.length();
if(lastname.find("sson")!=lastname.npos){
sex[i]=1;
father[i]=lastname.substr(0,len-4);
}
else if(lastname.find("sdottir")!=lastname.npos){
sex[i]=0;
father[i]=lastname.substr(0,len-7);
}
else if(lastname[len-1]=='m'){
sex[i]=1;
father[i]="nothing";
}
else if(lastname[len-1]=='f'){
sex[i]=0;
father[i]="nothing";
}
}
int k;
cin>>k;
for(int i=0;i<k;i++){
string a1,b1,a2,b2;
cin>>a1>>b1>>a2>>b2;
int id1,id2;
if(m.find(a1)==m.end()||m.find(a2)==m.end()){
cout<<"NA"<<endl;
continue;
}
id1=m[a1];
id2=m[a2];
if(sex[id1]==sex[id2]){
cout<<"Whatever"<<endl;
continue;
}
if(judge(a1,a2)){
cout<<"Yes"<<endl;
continue;
}
else cout<<"No"<<endl;
}
return 0;
}
还是有个测试点没过,欢迎各位大佬指正