CSP-J备考冲刺必刷题(C++) | AcWing 1253 家谱

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

Acwing:1253. 家谱 - AcWing题库

【题目描述】

现代的人对于本家族血统越来越感兴趣,现在给出充足的父子关系,请你编写程序找到某个人的最早的祖先。

【输入】

输入文件由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系由二行组成,用#name的形式描写一组父子关系中的父亲的名字,用+name 的形式描写一组父子关系中的儿子的名字;接下来用?name的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。规定每个人的名字都有且只有6个字符,而且首字母大写,且没有任意两个人的名字相同。最多可能有1000组父子关系,总人数最多可能达到50000人,家谱中的记载不超过30代。

【输出】

按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。

#George
+Rodney
#Arthur
+Gareth
+Walter
#Gareth
+Edward
?Edward
?Walter
?Rodney
?Arthur
$

【输出样例】

Edward Arthur
Walter Arthur
Rodney George
Arthur Arthur

【解题思路】

通过儿子记住父亲,找到祖先。map数据类型 h[s]: 表示儿子s的父亲

【算法标签】

《AcWing 1253 家谱》 #并查集#

【代码详解】

#include 
using namespace std;
string s, fa;
map<string, string> h;  // h[s]:表示儿子s的父亲
int main()
{
	while (cin >> s) {
		if (s=="$") return 0;  //数据读入结束标记
		char ch=s[0];  //取第一个标记字符
		s.erase(0, 1);  //删除第一个标记字符
		if (ch=='#') {
			fa = s;
			if (h[s]=="") h[s] = s;
		} else {
			if (ch == '+') h[s] = fa;
			else {
				cout << s << " ";
				while (h[s]!=s) s = h[s];
				cout << s << endl;
			}
		}
	}
	return 0;
}

【运行结果】

#George
+Rodney
#Arthur
+Gareth
+Walter
#Gareth
+Edward
?Edward
Edward Arthur
?Walter
Walter Arthur
?Rodney
Rodney George
?Arthur
Arthur Arthur
$

你可能感兴趣的:(c++,开发语言)