pta-乙级 1028 人口普查 (测试点3、4)

该程序用于人口普查,从输入的居民生日中筛选出合理年龄(0-200岁)的人口,并找出最年长和最年轻的居民。程序首先读取人口数量和每个人的姓名及生日,然后过滤掉不合理年龄的记录。通过比较日期找出最年长者和最年轻者的姓名,最后输出有效生日人数及最年长和最年轻者的姓名。

PTA-乙级 1028 人口普查 (测试点3、4)

某城镇进行人口普查,得到了全体居民的生日。现请你写个程序,找出镇上最年长和最年轻的人。

这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过 200 岁的老人,而今天是 2014 年 9 月 6 日,所以超过 200 岁的生日和未出生的生日都是不合理的,应该被过滤掉。

输入格式:

输入在第一行给出正整数 N,取值在(0,105];随后 N 行,每行给出 1 个人的姓名(由不超过 5 个英文字母组成的字符串)、以及按 yyyy/mm/dd(即年/月/日)格式给出的生日。题目保证最年长和最年轻的人没有并列。

输出格式:

在一行中顺序输出有效生日的个数、最年长人和最年轻人的姓名,其间以空格分隔。

输入样例:

5
John 2001/05/12
Tom 1814/09/06
Ann 2121/01/30
James 1814/09/05
Steve 1967/11/20

输出样例:

3 Tom John

注意点:

(1)当合理的年龄为0时,只输出num,不加空格;(测试点3)

(2)yyyy/mm/dd可以存为 string类型直接比较,如果存为 int 类型来计算比较年龄,可能会导致测试点4超时。

代码:

#include<iostream>
using namespace std;
struct person{
	string name;
	string age;
}per[100005];
int main(){
	int n;
	cin>>n;
	int num=n;
	string now="2014/09/06";
	string past="1814/09/06";
	string o_age="2222/02/02";
	string y_age="1818/08/08";
	string y_name,o_name;
	for(int i=0; i<n; i++){
		cin>>per[i].name>>per[i].age;
		if(per[i].age>now || per[i].age<past){
			num--;
		}
		else{
			if(per[i].age<o_age){
				o_age=per[i].age;
				o_name=per[i].name;
			}
			if(per[i].age>y_age){
				y_age=per[i].age;
				y_name=per[i].name;
			}
		}
	}
	if(num!=0){
		cout<<num<<' '<<o_name<<' '<<y_name<<endl;
	} 
	else{
		cout<<num<<endl;
	}	
}
<think>好的,我现在需要帮助用户解决关于PTA家庭房产题目(7-50)测试点3的问题。首先,用户明确提到了测试点3,可能这个测试点有特定的考察点或常见的错误。 首先,我得回忆一下PTA 7-50题的具体内容。家庭房产问题通常涉及数据结构,比如并查集,用来合并家庭成员,计算每个家庭的房产情况。题目可能要求统计每个家庭的人口、人均房产数量等信息,并按指定格式输出。 测试点3可能涉及一些特殊情况,比如多个家庭成员的复杂关系、输入中存在无效节点,或者合并家庭时的边界情况。根据引用[3]中的信息,题目中的链表结构可能涉及到节点地址的处理,但这里可能更偏向于并查集的应用。需要确认家庭成员的合并是否正确,尤其是当存在多个家族分支时。 接下来,用户可能需要解题思路和示例代码。根据常见的并查集问题,思路可能包括:收集每个人的信息,建立并查集,合并家庭成员(可能有多个家庭关系,如父母、配偶等),然后统计每个家庭的总人数、总房产数和人均值。 测试点3的常见错误可能包括未正确处理所有家庭成员关系,例如没有合并配偶的情况,或者处理多代家庭时出现遗漏。此外,输出顺序可能需要按照题目要求排序,比如先按人均面积降序,再按最小ID升序。如果排序条件有误,也可能导致测试点3失败。 示例代码需要正确使用并查集结构,处理输入数据,合并所有相关的家庭成员,然后进行统计和排序。需要注意数据输入的格式,比如如何处理家庭成员的ID、房产数量等。此外,输入中可能存在无效的节点,需要过滤掉这些节点,只处理有效的家庭成员信息。 可能还需要考虑家庭成员中存在多个关系的情况,比如一个人同时是另一个人的父母和配偶,这时候需要确保并查集正确合并所有关联的人。此外,处理最小ID作为家庭代表时,要确保在合并过程中始终选择较小的ID作为根节点。 最后,根据引用[1]和[2]中的例子,用户可能在代码结构或测试用例处理上有疑问,比如输入样例的解析是否正确,输出格式是否严格符合要求。特别是测试点3可能涉及较大的数据集或特殊情况,需要代码高效且逻辑正确。 总结下来,解题步骤可能包括:1. 读取并存储每个人的信息;2. 使用并查集合并家庭成员;3. 统计每个家庭的总人数、总房产和面积;4. 计算人均值;5. 按规则排序输出。需要特别注意合并所有可能的关系,并正确处理输入中的边界情况。</think>### PTA 7-50 家庭房产 解题思路 此题目需要通过**并查集**合并家庭成员,统计房产信息。测试点3可能考察以下关键点: 1. **复杂家庭关系合并**(如多代同堂、配偶关联) 2. **无效节点过滤**(引用[3]提到的NULL地址处理类似逻辑) 3. **输出排序规则**(先按人均面积降序,再按最小ID升序) #### 核心步骤 1. **数据预处理** - 用字典存储每个人的`房产套数/面积/父/母/子女/配偶`信息 - 标记所有出现过的有效ID 2. **并查集构建** ```python parent = {} def find(id): while parent[id] != id: parent[id] = parent[parent[id]] # 路径压缩 id = parent[id] return id def union(id1, id2): root1 = find(id1) root2 = find(id2) if root1 < root2: # 始终以较小ID为根 parent[root2] = root1 else: parent[root1] = root2 ``` 3. **关系合并** ```python for id in all_ids: parent[id] = id # 初始化 # 合并配偶、父母、子女 for id in data: if data[id]['配偶'] != -1: union(id, data[id]['配偶']) for parent_id in [data[id]['父亲'], data[id]['母亲']]: if parent_id != -1: union(id, parent_id) for child in data[id]['子女']: union(id, child) ``` 4. **统计输出** ```python families = defaultdict(lambda: {'members':[], 'total_house':0, 'total_area':0}) for id in all_ids: root = find(id) families[root]['members'].append(id) families[root]['total_house'] += data[id]['房产套数'] families[root]['total_area'] += data[id]['面积'] # 计算人均值并排序 result = [] for root in families: members = sorted(families[root]['members']) total = len(members) avg_house = families[root]['total_house'] / total avg_area = families[root]['total_area'] / total result.append( (min(members), total, avg_house, avg_area) ) result.sort(key=lambda x: (-x[3], x[0])) ``` ### 测试点3关键 1. **复杂关系合并验证**:确保同时存在父母、配偶、子女关系时能正确合并 2. **极小ID处理**:当出现ID为00001等5位编码时,注意字符串比较与数值比较的区别 3. **空数据处理**:当输入包含未出现在任何关系中的孤立节点时需要过滤 ### 示例代码框架 ```python def main(): n = int(input()) data = {} all_ids = set() # 数据读取部分 for _ in range(n): info = list(map(int, input().split())) id = info[0] # 解析父/母/子女/配偶/房产/面积等信息存入data # 并查集操作 # 关系合并代码 # 统计与输出 # 结果格式化输出部分 if __name__ == "__main__": main() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值