天梯題集——冰島人(隱藏條件:考慮嫡系)

小白小鄭發表於2020-11-27

前文

願天下有情人都是失散多年的兄妹 與 冰島人 解題思路幾乎是同理的,不過這裡需要考慮多一個是否嫡系的關係
(卡了我好久、又來一個隱藏條件,長知識、長知識…)。
用遞迴實現很容易出現超時,迴圈果然比遞迴效率高。
迴圈與遞迴效率的比較

冰島人

t1
t2
t3


解題難點

①、記錄資料——對映+結構體

struct node{
	string fa;
	int sex;
};
map <string, node> num;

第一次把對映和結構體結合起來,查詢方便了許多。


②、判斷 m1 與 m2 是否是嫡親

//判斷 s1 是否為 s2 的嫡系
bool judge1(string s1, string s2){
	for(string A=s1; !A.empty(); A=num[A].fa)
		if(A==s2) return false;
	return true;
}

③、m1 與 m2 五代以內無有公共祖先

//s1與s2五代以內無有公共祖先 
bool judge2(string s1, string s2){
	int i=1;
	string A, B;
	for(A=s1; !A.empty()&&i<=5; i++){
		int j=1;
		for(B=s2; !B.empty()&&j<=5; j++){
			if(A==B&&(i<5||j<5))
				return 0;
			B=num[B].fa;
		}
		A=num[A].fa;
	}
	return 1;
}

實現程式碼

#include<bits/stdc++.h>
using namespace std;

struct node{
	string fa;
	int sex;
};

map <string, node> num;
 
//判斷 s1 是否為 s2 的嫡系
bool judge1(string s1, string s2){
	for(string A=s1; !A.empty(); A=num[A].fa)
		if(A==s2) return false;
	return true;
}

//s1與s2五代以內無有公共祖先 
bool judge2(string s1, string s2){
	int i=1;
	string A, B;
	for(A=s1; !A.empty()&&i<=5; i++){
		int j=1;
		for(B=s2; !B.empty()&&j<=5; j++){
			if(A==B&&(i<5||j<5))
				return 0;
			B=num[B].fa;
		}
		A=num[A].fa;
	}
	return 1;
}

int main(){
	int n, k;
	scanf("%d", &n);
	for(int i=0; i<n; i++){
		string m, x;
		cin>>m>>x;
		//判斷性別
		switch(x[x.size()-1]){
			case 'm': num[m].sex = 'm';
					break;
			case 'f': num[m].sex = 'f';
					break;
			case 'n': num[m].fa = x.substr(0, x.size()-4);
					num[m].sex = 'm';
					break;
			case 'r': num[m].fa = x.substr(0, x.size()-7);
					num[m].sex = 'f';
					break;
		}
	}
	
	cin>>k;
	for(int i=0; i<k; i++){
		string m1, x1, m2, x2;
		cin>>m1>>x1>>m2>>x2;
		if(num.find(m1)==num.end()||num.find(m2)==num.end())
			cout<<"NA\n";
		else if(num[m1].sex==num[m2].sex)
			cout<<"Whatever\n";
		else{
			if(judge1(m1, m2)&&judge1(m2, m1)&&judge2(m1, m2))
				cout<<"Yes\n";
			else
				cout<<"No\n";
		}
	}
	
	return 0;
}

總結

看了網上一些程式碼,並沒有將全部情況都考慮到,但判題時能夠通過全部樣例,就很神奇。
比賽期間儘管提交,能混到分的話,就很妙…

相關文章