團隊天梯——“冰島人”——巧用STL

這個題考察的是散列熟練運用,利用STL中的unordered_map映射關係,建立家族樹

struct node

{

  string father;

  int sex;

};

unordered_map<string,node> Person;

問題1:如何判斷要查詢的點是否是樹中的點

string f;

Person.find(f) != Person.end() 爲true就是在樹裏面,如果爲false,則說明find()方法的指針從begin()到end()都沒有找到f這個鍵,說明Person裏沒有這個鍵

問題2:對於姓的後綴是f或者m這兩種特殊數據怎麼處理

f,m代表森林中,某樹的根,或者是家族的老祖宗,我們從輸入的f1開始尋找他的前輩的時候,找到祖宗就停下來了,所以不需要存儲f,m的姓,所以我們Person[f].father.empty() == true;

問題3:尋找相同前輩的誤區

1.共同祖先的必須同時都比兩個人的曾祖父都要年長,也就是在尋找時,某人的父親是另一個人曾祖父的父親,那這兩個人也是不可能的

2.如何解決問題3.1,需要我們寫一個兩層循環,x作爲外層循環遍歷x的前輩,對x的每一個前輩,都與y的所有前輩比較,這樣可以有效解決問題3.1

L2-030 冰島人 (25分)

2018年世界盃,冰島隊因1:1平了強大的阿根廷隊而一戰成名。好事者發現冰島人的名字後面似乎都有個“松”(son),於是有網友科普如下:

iceland.JPG

冰島人沿用的是維京人古老的父系姓制,孩子的姓等於父親的名加後綴,如果是兒子就加 sson,女兒則加 sdottir。因爲冰島人口較少,爲避免近親繁衍,本地人交往前先用個 App 查一下兩人祖宗若干代有無聯繫。本題就請你實現這個 App 的功能。

輸入格式:

輸入首先在第一行給出一個正整數 N(1<N≤10​5​​),爲當地人口數。隨後 N 行,每行給出一個人名,格式爲:名 姓(帶性別後綴),兩個字符串均由不超過 20 個小寫的英文字母組成。維京人後裔是可以通過姓的後綴判斷其性別的,其他人則是在姓的後面加 m 表示男性、f 表示女性。題目保證給出的每個維京家族的起源人都是男性。

隨後一行給出正整數 M,爲查詢數量。隨後 M 行,每行給出一對人名,格式爲:名1 姓1 名2 姓2。注意:這裏的是不帶後綴的。四個字符串均由不超過 20 個小寫的英文字母組成。

題目保證不存在兩個人是同名的。

輸出格式:

對每一個查詢,根據結果在一行內顯示以下信息:

  • 若兩人爲異性,且五代以內無公共祖先,則輸出 Yes
  • 若兩人爲異性,但五代以內(不包括第五代)有公共祖先,則輸出 No
  • 若兩人爲同性,則輸出 Whatever
  • 若有一人不在名單內,則輸出 NA

所謂“五代以內無公共祖先”是指兩人的公共祖先(如果存在的話)必須比任何一方的曾祖父輩分高。

輸入樣例:

15
chris smithm
adam smithm
bob adamsson
jack chrissson
bill chrissson
mike jacksson
steve billsson
tim mikesson
april mikesdottir
eric stevesson
tracy timsdottir
james ericsson
patrick jacksson
robin patricksson
will robinsson
6
tracy tim james eric
will robin tracy tim
april mike steve bill
bob adam eric steve
tracy tim tracy tim
x man april mikes
#include<iostream>
#include<unordered_map>
#include<string>
#include<cstdio>
using namespace std;
int n,m;
struct node
{
    int sex;
    string father;
};
unordered_map<string,node> Person;
int judge(string s1,string s2){
	int i=1,j;
	for( string A=s1; !A.empty(); i++,A=Person[A].father ){
		j=1;
		for( string B=s2; !B.empty(); j++,B=Person[B].father ){
			if(i>=5&&j>=5) return 1;
			else if(A==B&&(i<5||j<5)) return 0;
		}
	}
	return 1;
}
int main()
{
    cin>>n;
    for(int i = 0; i < n; i++)
    {
        string f,s;
        cin>>f>>s;
        int len = s.size();
        if(s.back() == 'm') Person[f].sex = 1;
        else if(s.back() == 'f') Person[f].sex = 0;
        else if(s.back() == 'n')
        {
            Person[f].sex = 1;
            Person[f].father = s.substr(0,len-4);
        }
        else if(s.back() == 'r')
        {
            Person[f].sex = 0;
            Person[f].father = s.substr(0,len-7);
        }
    }
    cin>>m;
    while(m--)
    {
        string f1,s1;
        string f2,s2;
        cin>>f1>>s1>>f2>>s2;
        if(Person.find(f1) == Person.end() || Person.find(f2) == Person.end())
            cout<<"NA"<<endl;
        else if(Person[f1].sex == Person[f2].sex)
            cout<<"Whatever"<<endl;
        else printf("%s\n",judge(f1,f2)?"Yes":"No");
    }
    return 0;
}

 

輸出樣例:

Yes
No
No
Whatever
Whatever
NA
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章