L2-030 冰岛人(map,并查集)

在这里插入图片描述在这里插入图片描述在这里插入图片描述
本题保证了不会出现同名的人,因此只需要保存名不需要保存姓,姓作为一个父亲结点保存,用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;
  }

还是有个测试点没过,欢迎各位大佬指正
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值