【天梯赛】7-10 冰岛人 (25 point(s))*(公共祖先)

穿越隧道

模仿大佬(简洁版)

#include <bits/stdc++.h>
using namespace std;
struct people{
	char sex;
	string fa;
};
map<string,people> mp;
bool chk(string a, string b){
	int i = 1,j = 0;
	for(string A = a; !A.empty(); A=mp[A].fa, i++){
		j = 1;
		for(string B= b; !B.empty(); B=mp[B].fa, j++){
			if(i >= 5 && j >= 5){//超时的点可能在这
				return true;
			}
			if(A == B && (i < 5 || j < 5)){
				return false;
			}
		}
	}
	return true;
}
int main(){
//	ios::sync_with_stdio(false);
//	cin.sync_with_stdio(false);//注释掉,也不会超时
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		string a,b;
		cin >> a >> b;
		if(b.back() == 'r'){
			mp[a] = {'f',b.substr(0,b.size() - 7)};
		}
		else if(b.back() == 'n'){
			mp[a] = {'m',b.substr(0,b.size() - 4)};
		}
		else{
			mp[a].sex = b.back();
		}
	}
	int m;
	cin >> m;
	string a,se1,b,se2;
	while(m--){
		cin >> a >> se1 >> b >> se2;
		if(mp.find(a) == mp.end() || mp.find(b) == mp.end()){
			puts("NA");
		}
		else if(mp[a].sex == mp[b].sex){
			puts("Whatever");
		}
		else{
			if(chk(a,b)) puts("Yes");
			else puts("No");
		}	
	}
	return 0;
}

代码较长版(AC)

#include <bits/stdc++.h>

using namespace std;
typedef pair<string,string> pii;
struct people{
	string fa;
	string sex;
};
string pos1="sson";
string pos2="sdottir";
map<string,people> p;
bool chk(string a, string b){
	int i = 1,j = 0;
	for(string A = a; A != ""; A=p[A].fa, i++){//因错写成A=p[a].fa无法顺利运行
		j = 1;
		for(string B= b; B != ""; B=p[B].fa, j++){
			if(i >= 5 && j >= 5){
				return true;
			}
			if(A == B && (i < 5 || j < 5)){
				return false;
			}
		}
	}
	return true;
}
int main(){
	ios::sync_with_stdio(false);
	cin.sync_with_stdio(false);
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		string fir,sec;
		cin >> fir >> sec;
		if(sec.find(pos1) != -1){
			string fa="";
			int len = sec.size();
			for(int i = 0; i < len - 4; i++){
				fa += sec[i];
			}
			string sex = "m";
			p[fir] = {fa,sex};//值fir的父亲是fa,fir的性别为m(男) 
		}
		else if(sec.find(pos2) != -1){
			string fa="";
			int len = sec.size();
			for(int i = 0; i < len - 7; i++){
				fa += sec[i];
			}
			string sex = "f";
			p[fir] = {fa,sex};
		}
		else{
//			string fa="";
			int len = sec.size();
//			for(int i = 0; i < len - 1; i++){
//				fa += sec[i];
//			}
			string sex = "";
			sex += sec[len-1];
			p[fir].sex = sex;
//			p[fa] = {fa,"x"};
		}
	}
	int m;
	cin >> m;
	while(m--){
		string na1,se1,na2,se2;
		cin >> na1 >> se1 >> na2 >> se2;
		int flag = 0; 
		if(p.find(na1) == p.end() || p.find(na2) == p.end()){
			puts("NA");
		}
		else if(p[na1].sex == p[na2].sex){
			puts("Whatever");
		}
		else{
			if(chk(na1,na2)) puts("Yes");
			else puts("No");
		}	
	}
	return 0;
}

思路不清晰的代码

在判断5代之内,思路不清晰
只能得20分(wa一个点,超时一个点)
wa的点估计是找是否为统一个

#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<string,string> pii;
const int N = 1e5 + 10;
string pos1="sson";
string pos2="sdottir";
map<string,pii> p;
map<string,pii> p2;
string find(string x){
	if(p[x].x != x){
		find(p[x].x);
	}
	return p[x].x;
}
string find1(string x){
	if(p2[x].x != x){
		x = find(p2[x].x);
	}
	return p2[x].x;
}
int main(){
	ios::sync_with_stdio(false);
	cin.sync_with_stdio(false);
	int n;
	cin >> n;
	for(int i = 0; i < n; i++){
		string fir,sec;
		cin >> fir >> sec;
		if(sec.find(pos1) != -1){
			string fa="";
			int len = sec.size();
			for(int i = 0; i < len - 4; i++){
				fa += sec[i];
			}
			string sex = "m";
			p[fir] = {fa,sex};//值fir的父亲是fa,fir的性别为m(男) 
		}
		else if(sec.find(pos2) != -1){
			string fa="";
			int len = sec.size();
			for(int i = 0; i < len - 7; i++){
				fa += sec[i];
			}
			string sex = "f";
			p[fir] = {fa,sex};
		}
		else{
			string fa="";
			int len = sec.size();
			for(int i = 0; i < len - 1; i++){
				fa += sec[i];
			}
			string sex = "";
			sex += sec[len-1];
			p[fir] = {fa,sex};
			p[fa] = {fa,"x"};
		}
//		cout << p[fir].x <<" " << p[fir].y << endl;
	}
	p2 = p;
//	if(p["sdf"].x != ""){
//		cout <<"sdfdfs" << endl;
//	}
//	else{
//		cout <<"DSFSDFSDF" << endl;
//	}
//cout << p["smith"].x << endl;
	int m;
	cin >> m;
	while(m--){
		string na1,se1,na2,se2;
		cin >> na1 >> se1 >> na2 >> se2;
		int flag = 0; 
		if(p[na1].x !="" && p[na2].x != ""){
			if(p[na1].y == p[na2].y){
				puts("Whatever");
			}
			else{
//				if(find1(na1) != find1(na2)){//并查集有问题 
//					cout << find1(na1) << " " << find1(na2) << endl;
//					puts("YES");
//				}
//				else{
					string fa1 = na1, fa2 = na2;
					int lee = 1,lev = 0;
					for(string fa1 = na1; p[fa1].x!=fa1; fa1 = p[fa1].x,lee++){
						lev = 1;
						for(string fa2 = na2; p[fa2].x!=fa2; fa2=p[fa2].x,lev++){
							if(lev >= 5 && lee >= 5){
								break;
							}
							if(fa2 == fa1 && (lev < 5 || lee < 5)){
								flag = 1;
								break;
							}
						}
					}
//					if(flag) puts()
//					while(fa1 != fa2){
//						int lev = 1;
//						while(fa1 != fa2){
//							fa2 = p[fa2].x;lev++;
//							if(lev >= 5){
//								flag = 1;
//								break;
//							}
//						}
//						if(lev >= 5){
//							flag = 1;
//							break;
//						}
//						if(fa1 == fa2){
//							if(lev < 5 && lee < 5){
//								break;
//							}
//							else{
//								flag = 1;
//								break;
//							}
//						}
//						fa1 = p[fa1].x;fa2 = p[na2].x;
//						lee++;
//					}
					if(flag == 0){
						puts("Yes");
					}
					if(flag == 1){
						puts("No");
					}
//				}
			}
		}
		else{
			puts("NA");
		}	
	}
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值